Getting back to the problems at hand: let's start with the function
get_rtc(), which maybe should be named
print_rtc(), but whatever.
Code: Select all
/* Entry Function */
int get_rtc(void)
{
while(isupdateinprogress());
uint8 hour = bcd_to_int(get_RTC_val(HOUR));
print(hour);
}
Now, for reference, let me post the definitions for the
string type:
(... I will leave it to others to pontificate on just how advisable this
typedef might or might not be...)
and the
print() function:
Code: Select all
void print (string ch)
{
uint16 i = 0;
uint8 length = strlength(ch)-1; //Updated (Now we store string length on a variable to call the function only once)
for(i;i<length;i++)
{
printch(ch[i]);
}
}
See the problem, yet? If not, here's a simpler example which should make it clear:
Code: Select all
#include <stdio.h>
int foo(void)
{
return 23;
}
void bar(char *baz)
{
printf("%s", baz);
}
void foo_bar()
{
bar(foo());
}
It should become especially obvious if you try running GCC with the
-Wall option, and I will bet you get a whole bunch of warnings like these:
Code: Select all
> gcc -Wall -c implconv.c
implconv.c: In function ‘foo_bar’:
implconv.c:15:9: warning: passing argument 1 of ‘bar’ makes pointer from integer without a cast [-Wint-conversion]
bar(foo());
^~~~~
implconv.c:8:16: note: expected ‘char *’ but argument is of type ‘int’
void bar(char *baz)
~~~~~~^~~
In other words, at least part of the problem is that you are passing a one-byte unsigned integer to a function which is expecting a char pointer (32 or 64 bit, depending, though the size mismatch is the least of the problems).
As thomtl already said, the solution is to convert the integer value into a string one, though the function thomtl mentioned,
itoa() is a) non-standard b) deprecated, and c) wouldn't be part of your own library anyway, as you haven't written it yet.
You will definitely need to write something similar eventually, though.
However... in this case, it may be easier to skip the integer conversion, and simply convert the BCD values - after all, this was always one of the putative advantages of using BCD (there were others, but most of them no longer really apply to modern systems, and the ones which do, are often poorly supported). So, if we assume (uh oh, assuming things...) that you are using ASCII or an ASCII-compatible encoding such as UTF-8 or Latin-1, you could add something like this to the
bcd.h and
bcd.c files:
bcd.h
bcd.c
Code: Select all
string bcd_into_str(bcd_t bcd, string buf, unsigned long offset)
{
unsigned long len;
char* ptr;
len = strlen(buf);
if (len < 2 || len < offset)
{
return NULL;
}
else
{
ptr = buf + offset;
// hex 30 == ASCII '0'
*ptr = (char) (bcd >> 4) + 0x30;
*(++ptr) = (char) (bcd & 0x0F) + 0x30;
}
return buf;
}
Note that it places the two characters
somewhere in the string; it is up to the programmer using it to make sure the string is big enough, delimited, etc. Caveat programmer.
Then for the function returning the RTC time, you would use something like this:
Code: Select all
/* get_rtc_time() - get the time from the real-time clock.
Value is given as a packed string; */
void get_rtc_time(string buf, uint32_t h_offset, uint32_t m_offset, uint32_t s_offset)
{
while(isupdateinprogress());
bcd_to_str(get_RTC_val(HOUR), buf, h_offset);
bcd_to_str(get_RTC_val(MINUTE), buf, m_offset);
bcd_to_str(get_RTC_val(SECOND), buf, s_offset);
}
You would use it something like this (not tested, I can't promise it will work right):
Code: Select all
char time[9];
strncpy("00:00:00", time, 9);
get_rtc_time(time, 0, 3, 6);
Which should fill in those "00"s with the hour, minute, and second values into the string
time.
While this peculiar setup? Because you might want to have different time string formats, and this will make that a little easier in some ways (and trickier in others). C programming is like that sometimes.
Note that you will need to implement your own strlen(), or at least borrow one from (for example) PDCLib, for this to work. OS programming is like that.