Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Change the number of software supported analog inputs
03-01-2013, 05:09 PM,
#1
Change the number of software supported analog inputs
I was wondering if it is possible to modify the quantity of software supported analog inputs.

The wiki says that Pinguino 26J50 has 10 hardware supported analog inputs, but only 5 of them are enabled by software, and when at least one of them is used, every analog-able input is configured as analog.

So, to get along better with this "all or none" condition maybe "all" could be a different number of pins.

In my case, just for using 1 analog input I am sacrificing 4 digital I/Os.
Reply
03-01-2013, 07:44 PM,
#2
RE: Change the number of software supported analog inputs
Hi Matias,
Yes it's possible and I agree with you. A long time ago I wrote a line in my TODO list to improve this. I still did nothing.
For your information, all the code is in p8/include/pinguino/core/analog.c
Régis


(03-01-2013, 05:09 PM)matias Wrote: I was wondering if it is possible to modify the quantity of software supported analog inputs.

The wiki says that Pinguino 26J50 has 10 hardware supported analog inputs, but only 5 of them are enabled by software, and when at least one of them is used, every analog-able input is configured as analog.

So, to get along better with this "all or none" condition maybe "all" could be a different number of pins.

In my case, just for using 1 analog input I am sacrificing 4 digital I/Os.
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
04-01-2013, 03:39 PM,
#3
RE: Change the number of software supported analog inputs
Yes it is very very simple modified the number or analos inputs, I never use the 26J50 , but I think thas it is the same as 2550 and 4550.
The pinguino fixed some PIC parameter, but is easy to change.
To enable 10 analogs ports for the 2550 or the 4550 . This is the way:

At setup() add:

ADCON1=0x05; //todos los AN0-AN10 en este caso
ADCON2=0xBD; //vref+ VDD vref- VSS se puede cambiar para aumentar la sensibilidad ( este es el default de todas maneras ).

And you need to create your own analogRead() functionusing modifing the standard code( as Regis said ) for example my routine is :

u16 anRead(u8 channel){ //especial para mas entradas
u16 result=0;
#ifdef PICUNO_EQUO
if(channel>=14 && channel<=16)
ADCON0=(channel-14)*4;
else if(channel>=17 && channel<=19)
ADCON0=(channel-13)*4;
#else
if(channel>=13)
ADCON0=(channel-13)*4;
else if(channel==0)
ADCON0=48; //12*4;
else if(channel==1)
ADCON0=40; //10*4;
else if(channel==2)
ADCON0=32; //8*4;
else if(channel==3)
ADCON0=36; //9*4;
else if(channel=4)
ADCON0=44; //11*4;
#endif
// ADCON2=0xBD;
ADCON0bits.ADON=1;
for (result=1;result<10;result++) __asm NOP __endasm;
ADCON0bits.GO=1;
while (ADCON0bits.GO);
result=ADRESH<<8;
result+=ADRESL;
ADCON0bits.ADON=0;
return(result);
}


Just read the michichip datasheed to use your our chip.

Regards.
Reply
04-01-2013, 05:10 PM, (This post was last modified: 04-01-2013, 05:11 PM by regis.)
#4
RE: Change the number of software supported analog inputs
Almost everything is possible with SFR manipulation ;-)
I was personally thinking about something easier that most people could use.
You know, when you use analogRead() in your .pde program, function analog_init() is called from main.c and all the 5 pins are declared as Analog. Instead, we could maybe call analog_init() from within analogread() but this time only for the desired pin. Of course, analog_init() should keep the previous state of ANCONx (or ADCONx) so that we could use analogRead() several times with different pins. Also, we would have to find a way to turn a pin from digital to analog and vice versa.



(04-01-2013, 03:39 PM)fvergniaud Wrote: Yes it is very very simple modified the number or analos inputs, I never use the 26J50 , but I think thas it is the same as 2550 and 4550.
The pinguino fixed some PIC parameter, but is easy to change.
To enable 10 analogs ports for the 2550 or the 4550 . This is the way:

At setup() add:

ADCON1=0x05; //todos los AN0-AN10 en este caso
ADCON2=0xBD; //vref+ VDD vref- VSS se puede cambiar para aumentar la sensibilidad ( este es el default de todas maneras ).

And you need to create your own analogRead() functionusing modifing the standard code( as Regis said ) for example my routine is :

u16 anRead(u8 channel){ //especial para mas entradas
u16 result=0;
#ifdef PICUNO_EQUO
if(channel>=14 && channel<=16)
ADCON0=(channel-14)*4;
else if(channel>=17 && channel<=19)
ADCON0=(channel-13)*4;
#else
if(channel>=13)
ADCON0=(channel-13)*4;
else if(channel==0)
ADCON0=48; //12*4;
else if(channel==1)
ADCON0=40; //10*4;
else if(channel==2)
ADCON0=32; //8*4;
else if(channel==3)
ADCON0=36; //9*4;
else if(channel=4)
ADCON0=44; //11*4;
#endif
// ADCON2=0xBD;
ADCON0bits.ADON=1;
for (result=1;result<10;result++) __asm NOP __endasm;
ADCON0bits.GO=1;
while (ADCON0bits.GO);
result=ADRESH<<8;
result+=ADRESL;
ADCON0bits.ADON=0;
return(result);
}


Just read the michichip datasheed to use your our chip.

Regards.
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
10-01-2013, 07:45 AM, (This post was last modified: 15-01-2013, 08:55 PM by matias.)
#5
RE: Change the number of software supported analog inputs
I am working on a library named adio.c (analog-digital-input-output) for the 26J50 that merges digitalw.c, analog.c and (partially ) io.c libraries.

The proposal is to use one initialization function, ioinit() (called at main.c), for both modes: digital and analog; and to switch between these by the means of pinmode(). Functions digitalwrite(), digitalread(), analogread() and toggle() remains the same.

I took the opportunity to change the actual pin masking to a more natural one: the pin name is the pin on chip.

For some reasons, the library is not working at all when loaded into the board. Which could be the problems?

Code:
#ifndef __ADIO__
#define __ADIO__

#include <pic18fregs.h>
#include <typedef.h>
#include <pin.h>

// Pin mode definitions
// ANALOG=2, INPUT=1, OUTPUT=0.

#include <const.h>

// Register bank shifts

#define sX 0  // Not implemented
#define sA 0  // No shift (i.e. PORTA)
#define sB 1  // Shift 1 bank (i.e. PORTB)
#define sC 2  // Shift 2 banks (i.e. PORTC)

// Register bits

#define _x 0x00  // 0000 0000
#define _0 0x01  // 0000 0001
#define _1 0x02  // 0000 0010
#define _2 0x04  // 0000 0100
#define _3 0x08  // 0000 1000
#define _4 0x10  // 0001 0000
#define _5 0x20  // 0010 0000
#define _6 0x40  // 0100 0000
#define _7 0x80  // 1000 0000

// ANx pin bit masking

const u8 ANbit[29] =
{
   _x,
   _x, _0, _1, _2,
   _3, _x, _4, _x,
   _x, _x, _x, _x,
   _3, _x, _x, _x,
   _x, _x, _x, _x,
   _4, _2, _0, _1,
   _x, _x, _x, _x
};

// ANx pin register masking

const u8 ANreg[29] =
{
   sX,
   sX, sA, sA, sA,
   sA, sX, sA, sX,
   sX, sX, sX, sX,
   sB, sX, sX, sX,
   sX, sX, sX, sX,
   sB, sB, sB, sB,
   sX, sX, sX, sX
};

// Rx pin bit masking

const u8 Rbit[29] =
{
   _x,
   _x, _0, _1, _2,
   _3, _x, _5, _x,
   _7, _6, _0, _1,
   _2, _x, _4, _5,
   _6, _7, _x, _x,
   _0, _1, _2, _3,
   _4, _5, _6, _7
};

// Rx pin register masking

const u8 Rreg[29] =
{
   sX,                   // 0 (No pin)
   sX, sA, sA, sA, // 1 (MCLR), 2 (RA0), 3 (RA1), 4 (RA2)  
   sA, sX, sA, sX, // 5 (RA3), 6 (Vcap), 7 (RA5), 8 (Vss)
   sA, sA, sC, sC, // 9 (RA7/OSC1), 10 (RA6/OSC2), 11 (RC0), 12 (RC1)
   sC, sX, sC, sC, // 13 (RC2), 14 (Vusb), 15 (RC4/D-), 16 (RC5/D+)
   sC, sC, sX, sX, // 17 (RC6), 18 (RC7), 19 (Vss), 20 (Vdd)
   sB, sB, sB, sB, // 21 (RB0), 22 (RB1), 23 (RB2), 24 (RB3)
   sB, sB, sB, sB  // 25 (RB4), 26 (RB5), 27 (RB6), 28 (RB7)
};

void ioinit(void)
{
/* PIC18F26J50 datasheet, section 2.7:
   Unused I/O pins should be configured as outputs and
   driven to a logic low state. Alternatively, connect a 1 kΩ
   to 10 kΩ resistor to VSS on unused pins and drive the
   output to logic low. */

// PIC18F26J50 distributes its IO pins into three ports: A, B and C.

// LATx registers control logic state of digital outputs.
// 0 is LOW and 1 is HIGH.
// All outputs are low.

  LATA = 0x00;
  LATB = 0x00;
  LATC = 0x00;

// TRISx registers control data direction of pins.
// 0 is OUTPUT and 1 is INPUT.
// All pins are outputs.

  TRISA = 0x00;
  TRISB = 0x00;
  TRISC = 0x00;

// ANCONx registers control analog/digital mode of pins.
// 0 is ANALOG INPUT and 1 is DIGITAL IO. When a pin is configured
// as analog input, digital input is disabled and reads '0'.
// All pins are digital IOs.

  ANCON0 = 0xFF; // AN0 to AN7
  ANCON1 = 0x1F; // AN8 to AN12

// ADCONx registers configure the A/D module.

  ADCON0=0x00; // VRef-=Vss, VRef+=Vdd
  ADCON1=0xBD; // 0b10111101: right justified, calibration normal, 20Tad, Fosc/16
}

void pinmode(u8 pin, u8 mode)
{
  u8 TRISbit  = Rbit[pin];         // TRISx bit
  u8 *TRISreg = Rreg[pin] + TRISA; // TRISx register
  u8 ANCONbit  = ANbit[pin];          // ANCONx bit
  u8 *ANCONreg = ANreg[pin] + ANCON0; // ANCONx register

  if (mode == ANALOG) {
    *ANCONreg &= (0xFF-ANCONbit); // Clear ANCONx bit (analog)
    *TRISreg |= TRISbit;          // Set TRISx bit (input)
  } else if (mode == INPUT) {
    *ANCONreg |= ANCONbit;        // Set ANCONx bit (digital)
    *TRISreg |= TRISbit;          // Set TRISx bit (input)
  } else {                        // mode == OUTPUT
    *ANCONreg |= ANCONbit;        // Set ANCONx bit (digital)
    *TRISreg &= (0xFF-TRISbit);   // Clear TRISx bit (output)
  }
}

void digitalwrite(u8 pin, u8 state)
{
  u8 LATbit  = Rbit[pin];        // LATx bit
  u8 *LATreg = Rreg[pin] + LATA; // LATx register
    
  if (state)
    *LATreg |= LATbit;        // Set LATx bit (high)
  else
    *LATreg &= (0xFF-LATbit); // Clear LATx bit (low)
}

void toggle(u8 pin)
{
  u8 LATbit  = Rbit[pin];        // LATx bit
  u8 *LATreg = Rreg[pin] + LATA; // Latx register
    
  if ((*LATreg & LATbit) == 0)
    *LATreg |= LATbit;        // Set LATx bit (high)
  else
    *LATreg &= (0xFF-LATbit); // Clear LATx bit (low)
}

u8 digitalread(u8 pin)
{
  u8 PORTbit  = Rbit[pin];         // PORTx bit
  u8 *PORTreg = Rreg[pin] + PORTA; // PORTx register
    
  if ((*PORTreg & PORTbit) == 0)
    return 0; // PORTx bit is not set (low)
  else
    return 1; // PORTx bit is set (high)
}

u16 analogread(u8 pin)
{
  u16 result=0;
    
/* Analog Channel Select bits

0000 = Channel 00 (AN0)  Pin 2
0001 = Channel 01 (AN1)  Pin 3
0010 = Channel 02 (AN2)  Pin 4
0011 = Channel 03 (AN3)  Pin 5
0100 = Channel 04 (AN4)  Pin 7
0101 = Channel 05 (AN5)  Not implemented
0110 = Channel 06 (AN6)  Not implemented
0111 = Channel 07 (AN7)  Not implemented
1000 = Channel 08 (AN8)  Pin 23
1001 = Channel 09 (AN9)  Pin 24
1010 = Channel 10 (AN10) Pin 22
1011 = Channel 11 (AN11) Pin 13
1100 = Channel 12 (AN12) Pin 21
1101 = (Reserved)
1110 = VDDCORE
1111 = VBG Absolute Reference (~1.2V) */

  switch (pin) {
  case AN0:
    ADCON0|=0b00000000;
    break;
  case AN1:
    ADCON0|=0b00000100;
    break;
  case AN2:
    ADCON0|=0b00001000;
    break;
  case AN3:
    ADCON0|=0b00001100;
    break;
  case AN4:
    ADCON0|=0b00010000;
    break;
/*  case AN5:
    ADCON0|=0b00010100;
    break;
  case AN6:
    ADCON0|=0b00011000;
    break;
  case AN7:
    ADCON0|=0b00011100;
    break; */
  case AN8:
    ADCON0|=0b00100000;
    break;
  case AN9:
    ADCON0|=0b00100100;
    break;
  case AN10:
    ADCON0|=0b00101000;
    break;
  case AN11:
    ADCON0|=0b00101100;
    break;
  case AN12:
    ADCON0|=0b00110000;
    break;
  case VDDCORE:
    ADCON0|=0b00111000;
    break;
  case VBG:
    ADCON0|=0b00111100;
    break;
  default:  
  }    

  ADCON0bits.ADON=1;     // Enable A/D module

  for (result=1;result<10;result++)
    __asm NOP __endasm;  // Wait an acquisition time
  
  ADCON0bits.GO=1;       // Start conversion
  while (ADCON0bits.GO); // Wait for conversion completion (GO=0)
  result=ADRESH<<8;      // Read A/D result registers
  result+=ADRESL;
  ADCON0bits.ADON=0;     // Disable A/D module
  return(result);
}

#endif /* __ADIO__ */

And this would be pin.h:

Code:
#ifndef __PIN_H
#define __PIN_H

/* This header file is aware of digital and analog IOs,
   comparators, interrupts, remappeable pins, CTMU. */

// Pin 1
// MCLR, 5.5V tolerant

// Pin 2
// Minimum output drive
#define A0    2
#define RA0   2
#define AN0   2
#define C1INA 2
#define RP0   2

// Pin 3
// Minimum output drive
#define A1    3
#define RA1   3
#define AN1   3
#define C2INA 3
#define RP1   3

// Pin 4
// Minimum output drive
#define A2    4
#define RA2   4
#define AN2   4
#define C2INB 4

// Pin 5
// Minimum output drive
#define A3    5
#define RA3   5
#define AN3   5
#define C1INB 5

// Pin 6
// Vcap

// Pin 7
// Minimum output drive
#define A5    7
#define RA5   7
#define AN4   7
#define RP2   7

// Pin 8
// Vss

// Pin 9
// OSC1, minimum output drive
#define A7    9
#define RA7   9

// Pin 10
// OSC2
#define A6    10
#define RA6   10

// Pin 11
// T1OSO
#define C0    11
#define RC0   11
#define RP11  11

// Pin 12
// T1OSI
#define C1    12
#define RC1   12
#define RP12  12

// Pin 13
#define C2    13
#define RC2   13
#define AN11  13
#define RP13  13
#define USERLED 13

// Pin 14
// Vusb

// Pin 15
// D- or digital input
#define C4    15
#define RC4   15

// Pin 16
// D+ or digital input
#define C5    16
#define RC5   16

// Pin 17
// 5.5V tolerant
#define C6    17
#define RC6   17
#define RP17  17

// Pin 18
// 5.5V tolerant
#define C7    18
#define RC7   18
#define RP18  18

// Pin 19
// Vss

// Pin 20
// Vdd

// Pin 21
#define B0    21
#define RB0   21
#define AN12  21
#define INT0  21
#define RP3   21

// Pin 22
#define B1    22
#define RB1   22
#define AN10  22
#define RP4   22

// Pin 23
#define B2    23
#define RB2   23
#define AN8   23
#define CTED1 23
#define RP5   23

// Pin 24
#define B3    24
#define RB3   24
#define AN9   24
#define CTED2 24
#define RP6   24

// Pin 25
// 5.5V tolerant
#define B4    25
#define RB4   25
#define KBI0  25
#define RP7   25

// Pin 26
// 5.5V tolerant
#define B5    26
#define RB5   26
#define KBI1  26
#define RP8   26

// Pin 27
// PGC, 5.5V tolerant
#define B6    27
#define RB6   27
#define KBI2  27
#define RP9   27

// Pin 28
// PGD, 5.5V tolerant
#define B7    28
#define RB7   28
#define KBI3  28
#define RP10  28

#endif /* __PIN_H */
Reply
24-01-2013, 03:30 PM, (This post was last modified: 24-01-2013, 03:30 PM by regis.)
#6
RE: Change the number of software supported analog inputs
I think the problem comes from these kind of line :
u8 *LATreg = Rreg[pin] + LATA;
where LATA is not the address of the register in memory but the content of this register.
Try to replace LATA with its address : 0x0F89
It is easier to complain than it is to do, but it is better to do than it is to complain.
Reply
25-01-2013, 08:09 AM,
#7
RE: Change the number of software supported analog inputs
(24-01-2013, 03:30 PM)regis Wrote: I think the problem comes from these kind of line :
u8 *LATreg = Rreg[pin] + LATA;
where LATA is not the address of the register in memory but the content of this register.
Try to replace LATA with its address : 0x0F89

Now that you mention it, I remember that the libraries in question do not use those definitions, but the address itself instead. I will keep working on this.

Thanks for replying!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)