Realization of Truth table in C - avr-gcc

I want to set various clock sources in a function as per the truth table below. Basically I want to write to the TCCR0B register(Atmega328) according to the parameter I pass to setClockSource function. The image of the table and registers is given below.
I am not able to makeout how best it can be done. I thought of using enum for various modes as below.
enum CLOCK_SOURCE{
NO_CLOCK_SOURCE=0x0;
NO_PRESCALING=0x01;
CLK_8=0x02;
// and so on
}
But the problem is in setClockSource() function, how should I write to TCCR0B register without affecting bits 3-7? Shall I first clear last 3 bits and then OR TIMER_MODE values with TCCR0B? Without clearing, I may not guarantee the correct values for last 3 bits I guess. What is the efficient way?
void setClockSource (enum CLOCK_SOURCE clockSource)
{
TCCR0B&=0xF8; // First Clear last 3 bits
TCCR0B|=clockSource;
}
Do we have library functions available to set clock source? I am using Atmega studio

Do it like this:
void setClockSource (CLOCK_SOURCE clockSource)
{
TCCR0B = TCCR0B & 0xF8 | clockSource;
}
Thus you will keep high bits and set lower bits.

Related

Is there a way to pass which "level" of structure is desired to a formula in (Arduino) C++?

I am not hugely experienced in C++ coding, but I learn pretty well as I go. But, I have not been able to properly query how to do this, may be using wrong terms or insufficiently expressing my desire. Here's the situation.
I have a lot of variables (3x12) that I have set up under a structure:
struct Tracking
{
String Title;
BoolArray n24hr;
bool State;
unsigned char Days, Weeks;
uint16_t Minutes, TotalMinutes, Daily, Weekly, Monthly, n7d[7], n4w[4];
} Components[3];
I also have code that performs basically the same thing 3 times but on different "levels", e.g. daily, weekly, monthly. It keeps tracks of status over those time periods, filling arrays, finding totals, and duty cycles, etc. It fills the minutes into days, and when that reaches a week, it puts the totals into a week format, and repeats until it reaches monthly levels. So basically, I have it doing something like:
in my main loop:
//calls status formula
StatusFormula();
in a separate file:
//status formula defined
void StatusFormula()
{
// for each element of Components:
//determine current status
//for daily
//add it to the correct spot in the array
//perform calculations on it
//when it reaches a week:
//add it to the correct spot in the next array
//perform calculations on it
//when it reaches a month:
//add it to the correct spot in the next array
//perform calculations on it
}
These calculations are all basically the same, the only differences are the structure member names & the constants for the calculations (i.e., MinsADay, DaysAWk, etc.).
I can get it to work this way, it just means a lot more lines and if I want to change something, I have to repeat it 3 times. What I want is something like this:
in my main loop:
//calls status formula
StatusFormula("Daily"); //sends the status formula information to decide which level (daily, weekly, monthly), it supposed to work on
if (Components[i].Minutes == MinsADay)
{
StatusFormula("Weekly"); //sends the status formula information to decide which level (daily, weekly, monthly), it supposed to work on
if (Components[i].Daily == DaysAWk)
{
StatusFormula("Monthly");
}
}
in a separate file:
//status formula defined
void StatusFormula()
{
//determine which level & variables to use (I would probably use case for this), then
//add it to the correct spot in the correct array
//perform calculations on it
}
I tried passing the level using a string, but it didn't work:
in my main loop:
StatusFormula(i, "Daily"); //sending data to formula, where i is value 0 to 2 for the Components array & defined earlier in the for loop.
in a separate file:
//formula defined as:
void StatusFormula(uint8_t counter, string level)
{Components[counter].level -= //etc... performing calculations as desired.
//so I thought this should evaluate to "Components[i].Daily -=" (& i would be a value 0 to 2) & treat it like the structure, but it doesn't work that way apparently.
I tried passing the structure & variable itself, but that didn't work either:
in my main loop:
StatusFormula(i, Components[i].Daily); //sending data to formula
in a separate file:
//formula defined as:
void StatusFormula(uint8_t counter, Tracking& level)
{level -= //etc... //(level should be Components[i].Daily -=" (& i would be a value 0 to 2)) this didn't work either.
I couldn't find any google searches to help me, and I trialed-and-errored a bunch of ways, but I couldn't figure out how to do that in C++, let alone on the Arduino platform. In Excel VBA, I would just have the variable passed as a string to the formula, which would substitute the word and then treat it like the variable that it is, but I couldn't make that happen in C++. Also to note, I am going to try and define this a separate file/tab so that my massive code file is easier to read/edit, in case that makes a difference. I would paste my code directly, but it is long and super confusing.
I guess what I am asking is how would I pass the structure and/or structure member to the formula in a way that would say the equivalent of:
case 1: //"Daily"
//use Components[i].Daily & Components[i].Minutes & MinsaDay
break;
case 2: //"Weekly"
//use Components[i].Weekly & Components[i].Days & DaysaWk
break;
//etc.
I feel like there should be a way & that I am just missing a small, vital piece. Several people in the comments suggested enums, and after researching, it might possibly be what I want, but I am having trouble visualizing it at the moment and need to do more research and examples. Any suggestions or examples on how to send the appropriate structure & members to the formula to be modified in it?

How to pass a 48-bit MAC address as a arguement in a function through a uint_8-bit variable?

Recently, I started working on a project relevant to emac and came across few doubts and blockages with respect to implementation, and decided to post my Q here to get some advise and suggestions from experienced people.
At present, I am working on interfacing the EMAC-DM9161A module with my SAM3x - Taiji Uino board for high speed ethernet communication.I am using the library developed by Palliser which is uploaded on Github as elechouse/EMAC-Demo. In the source code - ethernet_phy.c, I came across this function to initialize the DM9161A PHY component as follows:
unit8_t ethernet_phy_init(Emac*p_emac, uint8_t uc_phy_addr, uint32_t mck);
Problem: The argument uint8_t uc_phy_addr is an 8 bit register through which I want to pass a 48 bit MAC address such as - 70-62-D8-28-C2-8E. I understand that, I can use two 32 bit registers to store the first 32 bit of the MAC address i.e. 70-62-D8-28 in one 32 bit register and the rest 16 bit MAC address i.e. C2-8E in another 32 bit register. However, I cannot do this, since I need to use the above ethernet_phy_init function in which a unit8_t is used to pass the 48 bit MAC address. So, I'd like to know, how to make this happen?
Another Question: I executed some code to understand by some trial methods and came across some doubts,here is the code:
int main()
{
unit8_t phy_addr =49; //Assign a value 49 to 8 bit Reg
int8_t phy_addr1 = 49;
int phy_addr2 = 49;
cout<<phy_addr;
cout<<phy_addr1
cout<<phy_addr2;
getchar();
return 0;
}
Output Results:
1
1
49
So my doubt is, why is the output being displayed in ASCII character wherever I use a 8 bit variable to store the value 49, but when I use a normal 32 bit int variable to store 49, it displays a decimal value of 49. Why does this happen?. And lastly how to store MAC address in an 8 bit register?
About second question:
uint8_t/int8_t is same as unsigned/signed char and cout will handli it as char. Use static_cast<int> to print as number.
About first quiestion:
I never worked with emac, but judging by this example mac should be set this way:
#define ETHERNET_CONF_ETHADDR0 0x00
#define ETHERNET_CONF_ETHADDR0 0x00
#define ETHERNET_CONF_ETHADDR1 0x04
#define ETHERNET_CONF_ETHADDR2 0x25
#define ETHERNET_CONF_ETHADDR3 0x1C
#define ETHERNET_CONF_ETHADDR4 0xA0
#define ETHERNET_CONF_ETHADDR5 0x02
static uint8_t gs_uc_mac_address[] =
{ ETHERNET_CONF_ETHADDR0, ETHERNET_CONF_ETHADDR1, ETHERNET_CONF_ETHADDR2,
ETHERNET_CONF_ETHADDR3, ETHERNET_CONF_ETHADDR4, ETHERNET_CONF_ETHADDR5
};
emac_options_t emac_option;
memcpy(emac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
emac_dev_init(EMAC, &gs_emac_dev, &emac_option);
Regarding your second question: the first 2 variables are 8bit (one signed and one unsigned), so the ostream assumes they are chars (also 8bit wide) and displays the char representation for them ("1" = ASCII 49).
As for original question, i browsed a little bit the Atmel sources and the MAC address has nothing to do in ethernet_phy_init (all is at a much lower level):
uc_phy_addr - seems to be interface index
mck - seems to be a timer related value.
I figured it out, so I am going to answer my own question for those beginners like me who may encounter this same doubt.
Answer: As suggested by the members in the comments, yes they were right and thanks to them. The function parameter uint8_t uc_phy_addr represents the 5 bit port address in the PHY chip - Register and not the MAC Address, hence the address is set as 0x01 to enable only the receive pin and keeping the other 4 bits 0. The 4th bit is the CSR which is also set 0 in this case (for more details, Please refer data sheet of DM9161A).

c++ Variable values not updated correctly on GUI

I am debugging some simulation software that has been written partly in C++ and partly in Ada. On the GUI, there are two values displaying the ETA & TimeToGo of an entity moving in the simulation on any given leg of its journey, and for the remainder of the whole journey. The TimeToGo & ETA values that are displayed for the current leg are correct (i.e. how long it will take the entity to reach its current target destination from its current location). However, the TimeToGo & ETA values for the remainder of the whole journey are incorrect- approximately 40-50s lagging behind.
I have come across a couple of assignments in the code, and I am wondering if they are the wrong way round:
if(some condition){
mFlightPlanData[0] = fpMiniToteData;
} else {
mFlightPlanData[1] = fpMiniToteData;
}
mFlightPlanData[] is an array of flightPlans, of size 2- because each aircraft can have up to two flight plans at any one time- a primary and a secondary. fpMiniToteData is the variable used to display the flight plan data on the GUI.
Now, it appears to me that these assignments are the wrong way round- these seem to be saying:
Set the first element in the flight plan array equal to the value of the display data
else
Set the second element in the flight plan array equal to the value of the display data
However, what should be happening is that the display data should be being set to the value of either the first or second element in the flight plan array...
I tried to do this, by switching the assignments around, i.e.
if(some condition){
fpMiniToteData = mFlightPlanData[0];
} else {
fpMiniToteData = mFlightPlanData[1];
}
But I now get a compile error that says:
error C2678: binary '=': no operator found which takes a left-hand operand of type 'const...' or there is no acceptable conversion)
What does this error mean? Do I need to have defined a function that will convert the data type held in the array to the data type of the fpMiniToteData?
Any help would be much appreciated.
Edit 12/02/2015 # 1645
fpMiniToteData is defined in the function definition- the function that the code above belongs to:
void FlightPlanInterface::setFlightPlanData(
const FlightPlanMinitoteTypes::FlightPlanPerformanceDataViewId_Type viewId,
const FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& fpMiniToteData)
{
and mFlightPlanData is defined in a header file as follows:
private:
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant mFlightPlanData[2];

Converting bits from one array to another?

I am building a library for this vacuum fluorescent display. Its a very simple interface and I have all the features working.
The problem I am having now is that I am trying to make the code as compact as possable, but the custom character loading is not intuitive. That is the bitmap for the font maps to completely different bits and bytes to the display itself. From the IEE VFD datasheet, when you scroll down you see that the bits are mapped all over the place.
The code I have so far works like so:
// input the font bitmap, the bit from that line of the bitmap and the bit it needs to go to
static unsigned char VFD_CONVERT(const unsigned char* font, unsigned char from, unsigned char to) {
return ((*font >> from) & 0x01) << to;
//return (*font & (1 << from)) ? (1<<to) : 0;
}
// macros to make it easyer to read and see
#define CM_01 font+0, 4
#define CM_02 font+0, 3
#define CM_03 font+0, 2
#define CM_04 font+0, 1
#define CM_05 font+0, 0
// One of the 7 lines I have to send
o = VFD_CONVERT(CM_07,6) | VFD_CONVERT(CM_13,5) | VFD_CONVERT(CM_30,4) | VFD_CONVERT(CM_23,3) | VFD_CONVERT(CM_04,2) | VFD_CONVERT(CM_14,1) | VFD_CONVERT(CM_33,0);
send(o);
This is oviously not all the code. You can see the rest over my Google code repository but it should give you some idea what I am doing.
So the question I have is if there is a better way to optimize this or do the translation?
Changing the return statement on VFD_CONVERT makes GCC go crazy (-O1, -O2, -O3, and -Os does it) and expands the code to 1400 bytes. If I use the return statement with the inline if, it reduces it to 800 bytes. I have been going though the asm generated statements and current I am tempted to just write it all in asm as I am starting to think the compiler doesn't know what it is doing. However I thought maybe its me and I don't know what I am doing and so it confuses the compiler.
As a side note, the code there works, both return statements upload the custom character and it gets displayed (with a weird bug where I have to send it twice, but that's a separate issue).
First of all, you should file a bug report against gcc with a minimal example, since -Os should never generate larger code than -O0. Then, I suggest storing the permutation in a table, like this
const char[][] perm = {{ 7, 13, 30, 23, 4, 14, 33}, ...
with special values indicating a fixed zero or one bit. That'll also make your code more readable.

what the snippet of code does

I would like to know what the snippet of code does..
Drive[0] = 'A';
Drive[1] = ':';
Drive[2] = '\\';
Drive[3] = 0;
DriveMask = GetLogicalDrives();
for( anIndex = 0; anIndex < 26;
anIndex++ )
{
if( DriveMask & 1 )
{
Drive[0] = 'A' + anIndex;
DriveMask >>= 1;
}
}
Please let me know your answer.
Thank you for your time to read my post.
It checks if the lowest bit is set i.e. if there is an A drive. See GetLogicalDrives
It's enumerating all the possible attached drives between A:\ and Z:\ and checking to see whether they're removable (eg CD, floppy).
It loops 26 times, and each time
DriveMask >>= 1;
causes the bitmask to be shifted right by 1 bit, so that each logical drive can be tested for via the
if( DriveMask & 1 )
in succession.
GetDriveType() requires a drive path, so the label is constructed by adding the loop count to the letter A (so A, B, C, D, ..., Z) and leaving the previously-initialized :\ part in-place.
In C++ the & is a bitwise and.
So take the value Drives and do a bitwise with 0x00000001. The result should be 1 if the number is odd (only way to have an odd number is with the least significant bit is 1). Since 0 anded with 1 = 0, it basically zeroes out all the values except for the least significant bit. If that bit is 1, then the result is 1 and evaluates to true.
Otherwise it's 0, and you don't hit the if.
It checks if the number is odd.
& is a bit-wise AND comparison.
0101 (5)
& 0001 (1)
= 0001 (1 -- true)
1110 (14)
& 0001 (1)
= 0000 (0 -- false)
In this case, GetLogicalDrives returns a number whose bits indicate the presence of certain drives. The least significant bit (20, 1) indicates the A drive.
The expression Drives & 1 is testing to see that the result of a logical and between Drives and 0x00000001 is non-zero. Thus it is checking to see if Drives is odd.
actually api returns reply in binary format :- here what MSDN says about it
"
If the function succeeds, the return value is a bitmask representing the currently available disk drives. Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.
"
means
if( Drives & 1 ) // i dont understand this if condition here that what it checks ? {
}
Condition checking for digit drive presense.
The GetLogicalDrives function returns the set of logical drives where each drive is encoded as a bit (a binary digit, can be either 0 or 1). The drive labels start at "A" in bit 0 (the least significant bit). The bit is 1 if the drive is present, else it's 0. The & in the above code is a logical-AND operation to test bit 0. Essentially this code checks if the system has an "A:\" drive.
This piece of code does not do absolutely anything in the common understanding of the word do. This code contains only non-modifying query-type operations with no side effects, i.e. it makes some queries and verifies some conditions, but it doesn't make any actions based on the results of these conditions.
In other words, if this code was fed into some hypothetical super-optimizing compiler, which also knows the Windows API, that compiler would simply throw out (optimize away) the entire code, since it doesn't do anything.
Apparently, the code you provided is fake - it is not the whole code. Without the whole thing, it is impossible to say what it was supposed to do. However, if we guess that some useful functionality was supposed to be present between the {} in the following if
if( GetDriveType( Drive ) == DRIVE_REMOVABLE )
{
// Actually DO something here
}
then we can make an educated guess about what it was supposed to do. This code iterates though all possible single-letter drive designations in a Windows system. It checks whether a logical drive designated by that letter is present in the system. And if the drive is present, it checks whether this drive works with removable media. And, finally, if it is true, then it does something useful that you are not showing us. I don't know what it was. Nobody does.