Summary and analysis of IIC timing problems in mini2440 debugging

Publisher:delta14Latest update time:2024-06-20 Source: elecfansKeywords:mini2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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)

[1] [2]
Keywords:mini2440 Reference address:Summary and analysis of IIC timing problems in mini2440 debugging

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

mini2440 mounts linux folder via nfs
linux 1. Install nfs server sudo apt-get install nfs-kernel-server 2. Modify the configuration file /etc/exports vim /etc/exports Add in the last line /home/stu/nfs *(rw,sync,no_root_squash,no_subtree_check) Where /home/stu/nfs is the directory you want to mount 3. Port Mapping sudo service rpcbind restart
[Microcontroller]
Mini2440 Burning Linux System
According to the Guoembedded course, I failed to use dnw software to burn the system under Linux system, and a white screen appeared when I started the computer. Programming steps: 1. Keep the S2 switch turned to the nor flash switch, connect the serial port cable, open the serial port tool to observe the operatio
[Microcontroller]
Mini2440 Burning Linux System
Linux kernel configuration support for USB disk (for mini2440)
Configuring USB Because the USB flash drive uses SCSI commands, we first add SCSI support. In the Device Drivers menu, select SCSI device support, press Enter to enter the menu that appears, press the spacebar to select the option – SCSI device support, then enter and select SCSI disk support, return to the Device Dri
[Microcontroller]
Linux kernel configuration support for USB disk (for mini2440)
SPI subsystem diagram in Linux and SPI driver transplantation under mini2440
1. Detailed explanation of SPI subsystem block diagram: There are two types of devices on the SPI bus: one is the master end, which usually appears as a submodule of the SOC system. For example, many embedded MPUs often contain SPI modules. The other is the slave end, such as some SPI interface Flash, sensors,
[Microcontroller]
SPI subsystem diagram in Linux and SPI driver transplantation under mini2440
BOA server transplantation based on mini2440
Win7 system development board: mini2440 Virtual machine: Ubuntu 12.04 Preparation: Make sure the host and development board can communicate normally, that is, they can ping each other. For specific operation, please refer to my previous essay. 1. First download the boa source code from http://www.boa.org/ and co
[Microcontroller]
BOA server transplantation based on mini2440
How to configure NORFASH when using JLINK to download uboot to MINI2440?
Note: The following settings are applicable to downloading an empty board (i.e. no program in the chip) using JLINK, and are downloaded to NORFALSH. 1.Target Interface (as shown below): 2.CPU settings: CPU settings include 3 parts: 2.1 Select CPU (S3C2440A is ARM920T core)   2.2 Set RAM address and size (S3
[Microcontroller]
How to configure NORFASH when using JLINK to download uboot to MINI2440?
mini2440_uboot transplantation notes
1. Preparation    Download software: u-boot Download address: ftp://ftp.denx.de/pub/u-boot/    u-boot-2009.11.tar.bz2 is the reference document version of "friendlyARM"    u-boot-2010.03.tar.bz2 is the reference document version of "Shen Embedding - uboot Transplantation"   This time we use the newer uboot versi
[Microcontroller]
uboot ported to mini2440
The goal of this article is to complete the porting of mini2440 so that uboot can run normally on mini2440. 1. Establish the development environment of mini2440. uboot supports many CPUs, including mini2440. But the version I chose is relatively old, 2009.08. So there is no mini2440 related files in it. Therefore,
[Microcontroller]
uboot ported to mini2440
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号