Description: mini2440 platform, wince6.0 system, vs2005
After several months of study and pause, I finally added the IIC bus simulated by GPIO under wince and realized the transplantation of IIC. The chip of IIC is SHT21 temperature and humidity chip.
The reason why I haven't figured out IIC for so long is that I implemented it very early in ADS, but it was always wrong when I added it to the system! The oscilloscope captured and found that the timing was wrong after the chip was reset. I searched and searched but couldn't figure out what was going on! Now I'm stuck.
I'm stuck in a vicious circle and can't get out of it!
I posted online and netizens gave me a lot of tips. Thank you! Jonsenwu netizen's words reminded me! When the driver is added to the system, the system scheduling takes time, and the delay of the driver will be extended! According to his tips, I also asked him for further advice. I would like to thank him here! Adjust the priority of the driver so that it always keeps the right to use the CPU during operation. The delay function tested under ADS will not be the same under the system!
Things I learned from this transplant:
1. Knowledge about priority in wince
The following is the code: used to implement priority preemption
//dwThreadID = GetCurrentThread(); //Get thread ID
//dwThreadPri = CeGetThreadPriority(dwThreadID); //Get thread ID priority
//dwThreadQuantum = CeGetThreadQuantum(dwThreadID); //Get thread time slice parameter
//CeSetThreadPriority(dwThreadID, 0);// Set current thread priority to the highest
//CeSetThreadQuantum(dwThreadID, 0); //Set current thread time slice to 0 to keep CPU ownership
//
//.......... (function for operating i2c)
//
//CeSetThreadQuantum(dwThreadID, dwThreadQuantum); //Restore normal time slice
//CeSetThreadPriority(dwThreadID, dwThreadPri); //Restore normal priority
Note: There are two functions for setting the priority, one function can set the priority from 0 to 255 (CeSetThreadPriority()), and the other function can only set the application priority from 248 to 255 (SetThreadPriority())!!
After the IIC debugging is successful, there is another problem in passing the data to the application. First, I implemented the transfer in XXX_IOControl, but no data came out no matter how I tried. Finally, I put it in XXX_Read and it was OK. Here I have to explain the problem about memcpy. As follows:
2. Understanding of memcpy function
Let’s first look at the problematic writing:
unsigned short SHT_Data[2];//
memcpy(pBuffer, SHT_Data, 2);//output
The only data my application reads is the temperature, the humidity is a very high number! I'm sure an expert will see the problem at a glance!
This is because: the copy of the memcpy function is based on bytes. The number of copies I made above is 2, so only the temperature is normal, and the humidity is not copied at all.
The correct method is 4 bytes: memcpy(pBuffer, SHT_Data, 4); //output
3. GPIO description
Here I have to despise the friendly arm's technical service again! I originally used the default two pins of 2440 for GPIO (the default ones were connected to EEPROM and Camera!!, it would be strange if they were correct!), and finally found the free pins of SPI0 to get it done.
The code can be found at: http://www.linuxidc.com/Linux/2012-11/74419p2.htm
Using the simulated IIC timing of the IIC IO port on mini2440 to drive a peripheral chip, the ADS debugging is correct, but it does not work when added to the system. The priority of the driver is also increased, but it is still incorrect.
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
//volatile INTreg *s2440INT = (INTreg *)INT_BASE;
float SHT_Data[2];///tmp
HANDLE hDevSHT21;
DWORD SHT2x_Option_ThreadFuc(LPVOID Context);
void Virtual_Alloc(); // Virtual allocation
////////////////////////////////////////////////////// ////////////////////////////
///////////////////////////////////I2C.c source/////////////// ////////////////////////////
#define noACK 0
#define aCk 1
#define SCL_OutEnable s2440IOP->rGPECON =( s2440IOP->rGPECON | 0x30000000 ) & 0xDFFFFFFF //28 config SCL as output
#define SDA_OutEnable s2440IOP->rGPECON =( s2440IOP->rGPECON | 0xC0000000 ) & 0x7FFFFFFF //30config SDA as output
#define SDA_OutDisable s2440IOP->rGPECON =( s2440IOP->rGPECON & 0x3fffffff)//config SDA as input
#define SCL_Set s2440IOP->rGPEDAT |= (1 << 14) //SCL output "1"
#define SCL_Clear s2440IOP->rGPEDAT &= ~(1 << 14) //SCL output "0"
#define SDA_Set s2440IOP->rGPEDAT |= (1 << 15) //SDA output "1"
#define SDA_Clear s2440IOP->rGPEDAT &= ~(1 << 15)
void Delay_us(U32 uS)
{
volatile DWORD dwCounter;
dwCounter = 100 * uS;
while(dwCounter--);
}
void I2c_Initialize ()
{ // put setup code here
SCL_OutEnable; // set gpio6->SCL as output
SCL_Set; // set SCL = "1"
SDA_OutDisable; // set gpio7->SDA as input
SDA_Set;
Delay_us(100); // let I2C device ready
}
//================================================ ==============================
void I2c_StartCondition ()
//================================================ ==============================
{
SDA_OutEnable; // set SDA as output
//SCL_OutEnable; //!!
SDA_Set;
SCL_Set;
Delay_us(1);
SDA_Clear;
Delay_us(5);
SCL_Clear;
Delay_us(5);
}
//================================================ ==============================
void I2c_StopCondition ()
//================================================ ==============================
{
SDA_OutEnable; // set SDA as output
//SCL_OutEnable; //!!
SDA_Clear;
SCL_Clear;
Delay_us(1);
SCL_Set;
Delay_us(5);
SDA_Set;
Delay_us(5);
}
//------------------------------------------------ ----------------------------------
unsigned char I2c_WriteByte(unsigned char value)
// writes a byte on the Sensibus and checks the acknowledge
//------------------------------------------------ ----------------------------------
{
// dwThreadID = GetCurrentThread();
//dwThreadPri = CeGetThreadPriority(dwThreadID);
//dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
//CeSetThreadPriority(dwThreadID, 0);/
//CeSetThreadQuantum(dwThreadID, 0);
//
// . . . . . . (This part is the function for operating i2c)
//
//CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
//CeSetThreadPriority(dwThreadID, dwThreadPri);
HANDLE dwThreadID = GetCurrentThread();
DWORD dwThreadPri = CeGetThreadPriority(dwThreadID);
DWORD dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
CeSetThreadPriority(dwThreadID, 0);
CeSetThreadQuantum(dwThreadID, 0);
int error=0, i1=0, i2=0;
for(i2 = 0; i2 < 8; i2++ )
{ // setup data onto SDA
if(value & 0x80){
SDA_Set; //SetSDA( 1 );
}
else{
SDA_Clear; //SetSDA( 0 );
}
Delay_us(1); //I2C timing: data setup time > 200ns
//issue a clock
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: SCL high time > 0.6us
SCL_Clear; //SetSCL( 0 );
Delay_us(2); //I2C timing: SCL low time > 1.3us
value= value<< 1;
}
//check ACK(Low state) from I2C device
SDA_OutDisable; //set SDA as input
Delay_us(1); //I2C timing: data(from I2C device) setup time > 200ns
SCL_Set; //SetSCL( 1 ); // issue a clock
Delay_us(1); //I2C timing: SCL high time > 0.6us
if(s2440IOP->rGPEDAT>>15) //read ACK_BIT issued from I2C device
{
// NO ACK, so setup STOP condition
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: stop setup timing > 0.6us
SDA_Set; //SetSDA( 1 ); SDA is in input status!
return -(i1+1); // no acknowledgment -> failed
}
SCL_Clear; //SetSCL( 0 );
Delay_us(2); //I2C timing: SCL low time > 1.3us
//check ACK passed, config SDA as output for further outputing
SDA_OutEnable;
// backup the thread priority;
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
return 0;
}
//------------------------------------------------ ----------------------------------
unsigned char I2c_ReadByte(unsigned char ack)
//------------------------------------------------ ----------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
HANDLE dwThreadID = GetCurrentThread();
DWORD dwThreadPri = CeGetThreadPriority(dwThreadID);
DWORD dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
CeSetThreadPriority(dwThreadID, 0);
CeSetThreadQuantum(dwThreadID, 0);
unsigned char i,val=0;
int i2=0,ub[1];
SDA_OutDisable; //SetSDADir( 0 ); // set SDA as input
// then read a byte
for(i2 = 0; i2 < 8; i2++)
{
ub[0] = ub[0] << 1;
//issue a clock
SCL_Set; //SetSCL( 1 );
//DelayInuSec(1); //I2C timing: SCL high time > 0.6us
if(s2440IOP->rGPEDAT>>15) // read SDA
{
ub[0] = ub[0] | 0x01;
}
SCL_Clear; //SetSCL( 0 );
Delay_us(5); //I2C timing: SCL low time > 1.3us
}
//issue ACK condition properly
SDA_OutEnable;
if (ack)
{ SDA_Clear; }
else
{ SDA_Set; }
Delay_us(1); //I2C timing: data setup time > 200ns
SCL_Set; //SetSCL( 1 );
Delay_us(1); //I2C timing: SCL high time > 0.6us
SCL_Clear;
Delay_us(2); //I2C timing: SCL low time > 1.3us
// backup the thread priority;
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
return ub[0];
}
/////////////////////////////// SHT2x.c source ////////////////// ///////////////////////
//================================================ ===========================
unsigned char SHT2x_MeasureHM(etSHT2xMeasureType eSHT2xMeasureType, unsigned int *pMeasurand)
Previous article:Definition of 2440GPIO port in Linux
Next article:mini2440 ADC adjustable resistor driver development source code (miscellaneous device driver framework)
Recommended ReadingLatest update time:2024-11-23 03:16
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- How much does it cost to build a TMR magnetoresistive switch from development to manufacturing?
- Arrow Electronics Online Seminar: Intel FPGA Deep Learning Acceleration Technology Registration Open~~
- Review summary: Arteli AT32WB415 series Bluetooth BLE 5.0 MCU, free first-hand experience!
- Adjustable Car Battery Charger
- Nexperia ESD Application Notes Free Download | Read ESD Tips and Answer Questions to Win Prizes
- The new version is so beautiful, I decided not to update it for the time being!
- [SAMR21 New Gameplay] 12. Driving OLED
- [NXP Rapid IoT Review] Adding USB Serial Port Simulation Function to Rapid
- Detailed explanation of five classic power supply circuits
- MSP430 MCU Development Record (8)