adc3208 - c code - problems...
Javalin
Posts: 892
Hello all,
Hopefully somebody can spot what I can't see!
Channel 0 works 100% ok - the others return gibberish.· Checked the circuit and the inputs as far as I can.· I guess something is going out of sequence here - but why then is channel 0 working all the time?· The loops appear to be outputing/inputting the correct number of bits.
Thanks!
James
Edit -> Included variable declarations & pins.
Post Edited (Javalin) : 9/2/2009 5:44:13 AM GMT
Hopefully somebody can spot what I can't see!
Channel 0 works 100% ok - the others return gibberish.· Checked the circuit and the inputs as far as I can.· I guess something is going out of sequence here - but why then is channel 0 working all the time?· The loops appear to be outputing/inputting the correct number of bits.
Thanks!
[color=#008000][color=#008000]// pins...[/color][/color] [color=black]int adc_clk = 15; int adc_di = 14; int adc_do = 13; int adc_cs = 12;[/color] [color=#000000]//code[/color] [color=black]void main(void)[/color] [color=black]{[/color] [color=black] int i = 0; int result = 0; int spiData = 0; int adcMUX = 0; int adcData = 0; int adcChannel[noparse][[/noparse]8]; [/color] SET (DIRA, adc_cs); [color=#008000][color=#008000]// output [/color][/color] SET (DIRA, adc_do); [color=#008000][color=#008000]// output [/color][/color] SET (DIRA, adc_clk); [color=#008000][color=#008000]// output [/color][/color] CLR (DIRA, adc_di); [color=#008000][color=#008000]// input[/color][/color] CLR (OUTA,adc_cs); [color=#008000][color=#008000]// low[/color][/color] msleep(10); [color=#008000][color=#008000]// wait a tick[/color][/color] SET (OUTA,adc_cs); [color=#008000][color=#008000]// high [/color][/color] [color=#008000][color=#008000] // ADC![/color][/color] while(TRUE) { printf([i]"is -> "[/i]); putchar(32); for (i=0; i<8; i++) { adcMUX = 0b00011000 + i; [color=#008000][color=#008000]// command byte[/color][/color] CLR (OUTA,adc_cs); [color=#008000][color=#008000]// low [/color][/color] CLR (OUTA,adc_do); [color=#008000][color=#008000]// low[/color][/color] CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low[/color][/color] shiftout (adcMUX,8); [color=#008000][color=#008000]// output the cmd byte [/color][/color] CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low[/color][/color] SET (OUTA,adc_clk); [color=#008000][color=#008000]// high [/color][/color] CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low[/color][/color] SET (OUTA,adc_clk); [color=#008000][color=#008000]// high[/color][/color] CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low [/color][/color] adcChannel[noparse][[/noparse]i] = shiftin(12); [color=#008000][color=#008000]// clock in the data[/color][/color] SET (OUTA,adc_cs); [color=#008000][color=#008000]// high [/color][/color] FdSerial_dec(adcChannel[noparse][[/noparse]i]); putchar(32); msleep(10); } putchar(13); msleep(500); } } int shiftin(short bitCnt) { short i=0; int data=0; int inputpinMask = 1 << adc_di; for(i=0; i<bitCnt; i++) { CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low[/color][/color] SET (OUTA,adc_clk); [color=#008000][color=#008000]// high [/color][/color] data <<= 1; [color=#008000][color=#008000]// shift-left the data [/color][/color] [color=#008000][color=#008000] //data |= ((INA & inputpinMask) != 0); // read the port[/color][/color] if (INA & inputpinMask) { data |= 1; } } return data; } void shiftout(int spiData,short bitCnt) { short i=0; for(i=0; i<bitCnt; i++) { [color=#008000][color=#008000] // test for state of bit (n) [/color][/color] if (spiData & (1 << i)) { SET (OUTA,adc_do); } else { CLR (OUTA,adc_do); } [color=#008000][color=#008000] // pulse the clock[/color][/color] SET (OUTA,adc_clk); [color=#008000][color=#008000]// high[/color][/color] CLR (OUTA,adc_clk); [color=#008000][color=#008000]// low [/color][/color] } }
James
Edit -> Included variable declarations & pins.
Post Edited (Javalin) : 9/2/2009 5:44:13 AM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
April, 2008: when I discovered the answers to all my micro-computational-botherations!
And I'll kill you[noparse][[/noparse]tm] if you are using a global 'i' for the counter in main.
I'll kill you:
<
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
There's no way to tell whether this is a problem without seeing your circuit. The mystery why the channel #0 works remains unexplained so I'd expect that you have the wires right.
BTW, you need to have analog signal connected to a channel pin, if you just leave the pin unconnected it won't show 0 (or close to 0), it will produce numbers all over the range. Could this be the case?
Also I am not sure you have your pre clocks correct. If I were you I would let the shift in routine take care of the null bit by adcChannel = shiftin(13); and dropping the extra clocks between.
Last time I debugged communication with this chip I used jazzed's prop based logic program to look at the pattern.
I have no clue about hardware issues, but regarding global i vs. local i, the compiler "does the right thing" (tm) . That is, per C standard, if a local variable is visible, that will be used instead of a global variable.
The original program is incomplete so we can only guess that main() does in fact use a global i. Regardless, that should not cause any issue either way.
// richard
I'm not!· The code isn't finished either way!
Erik
Tried that - no joy.
All,
The output is weird - ch0 works nicely goes from 0 (ish) to 4095 but the other 7 channels all seems to move with the change when I vary the input to channel 3 for example!
Hardware wise its on·a PPDB board - I currently have a pot on ch0 and 3.· Tried 3.3v and 5v voltage sources - didn't help.· Tried different I/O pins.
Its almost like its reading differential channels or reading the LSB first data somehow.
I'll re-write the code in SPIN to test the circuit.· I have some PASM that works well - that this is based on.· Found some weirdness looking at the I/O via an O-scope.
Thanks all,
James
Post Edited (Javalin) : 9/2/2009 7:19:58 AM GMT
Richard - if I use local variables are they kept within the cog that piece of code runs under? I.e. like PASM? I ask cause SPIN obviously has no local variables.
Cheers,
James
Spin has local variables in methods ... i.e. pub start(codep, parmp) | j, k ... guess which ones are local (normally kept in the stack).
There is nothing in the code you posted that suggests you are using multiple cogs. What do you have connected to the ADC channels?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
I think Achmed, the dead terrorist is funny enough for that quote. Hope none took it too serious.
But a global counter is really something that needs punishment. If he would have used the same i in the other functions, the result would have been quite confusing.
@James:
Use #defines for adc_clk etc.
These are constants, not variables.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Post Edited (Nick Mueller) : 9/2/2009 7:12:28 AM GMT
(yeah the 0b is probably a microchip thing for binary)
It explains why channel0 works - as the code is the same both ways arround (i.e. 00011000)!
Doh. Good spot.
I'll post the fixed C code and the SPIN equivalent tonight
Cheers again all,
James
the compiler doesn't like:
#define adc_clk 15 /* or whatever */
Help?
james
Did he say "I don't like that"?
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
I'll post the exact error tonight
James
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
James
#define adc_cs=15;
#define adc_cs 15;
and then (which worked)
#define adc_cs 15
(no ";")
James
Out of interest I took some timing's via O'scope from when CS goes LOW to when it returns to HIGH - a single channel read!
C·= 175us
SPIN = 1.89ms
The output (Parallax Serial Terminal) looks like:
And the SPIN code:
output is:
I've left the debug in the SPIN object.
James
Post Edited (Javalin) : 9/3/2009 8:03:03 PM GMT
But I wrote that.
That would be:
You shouldn't mix printf and FdSerial_bin etc. Albeit it doesn't matter here, the is no guaranty that the two make some buffering or not.
OK, %x doesn't print a binary, only a hex. And the stdio with format specifiers (length etc.) is quite expensive size-wise.
thats:
putchar(32); would be putchar(' '); and putchar(9); putchar('\t');
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
One of my biggest ICC frustrations is that some format specifiers just don't work at all ... I could be mistaken, but I don't remember %04x working at all in any printf mode.
Using printf, sprintf, snprintf, vfprintf, yada yada carries a big cost. If you are using it, make sure you take full advantage of it. It's not entirely clear how ICC interprets the format specifiers (perhaps the ICC on-line manual addresses this), but you can get a feel by looking at a sprintf man page like this: linux.die.net/man/3/sprintf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
Thanks for the formatting suggestions - hadn't thought of that!
That would be:
Is there a binary formatter for printf?· Google wasn't my friend on that one!
Post updated with the rest though!
James
But I wrote that, right?
> One of my biggest ICC frustrations is that some format specifiers just don't work at all ... I could be mistaken,
> but I don't remember %04x working at all in any printf mode.
No, that works! You have to select the printf-lib one level higher (project settings IIRC). There are three: with float (not that one), full format specifiers (or something like this) and "primitive". Default is primitive, and this one doesn't understand field lengths.
But, as I said, it is quite bigger in code-size!
> Is there a binary formatter for printf?
Officially not. Maybe ICC has one but I really don't remember. I guess not. But programmers can translate hex to bin anyhow.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
The '#define someConstant' is one way. An other way (and more up to date) is to write 'const int 4711'.
Some compilers might emmit less code with '#define'. I didn't check with ICC.
But anyhow, you have to learn that #define, #ifdef, #endif stuff, it's good for debugging, production code, different versions (language, platform, etc).
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
No, you wrote:
> You shouldn't mix printf and FdSerial_bin etc. Albeit it doesn't matter here, the is no guaranty that the two make some buffering or not.
I prefer using const int ...; over #define since you avoid "label" collision problems in large projects. I prefer static const int ...; where possible of course.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
Label!? That sounds like a four letter word, like 'goto'. I'm shocked!
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools