EmbLogic's Blog

LoRaWAN Technology

LoRaWAN™ is a Low Power Wide Area Network (LPWAN) specification intended for wireless battery operated Things in a regional, national or global network. LoRaWAN targets key requirements of Internet of Things such as secure bi-directional communication, mobility and localization services. The LoRaWAN specification provides seamless interoperability among smart Things without the need of complex local installations and gives back the freedom to the user, developer, businesses enabling the roll out of Internet of Things.
LoRaWAN network architecture is typically laid out in a star-of-stars topology in which gateways is a transparent bridge relaying messages between end-devices and a central network server in the backend. Gateways are connected to the network server via standard IP connections while end-devices use single-hop wireless communication to one or many gateways. All end-point communication is generally bi-directional, but also supports operation such as multicast enabling software upgrade over the air or other mass distribution messages to reduce the on air communication time.
Communication between end-devices and gateways is spread out on different frequency channels and data rates. The selection of the data rate is a trade-off between communication range and message duration. Due to the spread spectrum technology, communications with different data rates do not interfere with each other and create a set of “virtual” channels increasing the capacity of the gateway. LoRaWAN data rates range from 0.3 kbps to 50 kbps. To maximize both battery life of the end-devices and overall network capacity, the LoRaWAN network server is managing the data rate and RF output for each end-device individually by means of an adaptive data rate (ADR) scheme.
National wide networks targeting internet of things such as critical infrastructure, confidential personal data or critical functions for the society has a special need for secure communication. This has been solved by several layer of encryption:
Unique Network key (EUI64) and ensure security on network level
Unique Application key (EUI64) ensure end to end security on application level
Device specific key (EUI128)
LoRaWAN has several different classes of end-point devices to address the different needs reflected in the wide range of applications:
Bi-directional end-devices (Class A): End-devices of Class A allow for bi-directional communications whereby each end-device’s uplink transmission is followed by two short downlink receive windows. The transmission slot scheduled by the end-device is based on its own communication needs with a small variation based on a random time basis (ALOHA-type of protocol). This Class A operation is the lowest power end-device system for applications that only require downlink communication from the server shortly after the end-device has sent an uplink transmission. Downlink communications from the server at any other time will have to wait until the next scheduled uplink.
Bi-directional end-devices with scheduled receive slots (Class B): In addition to the Class A random receive windows, Class B devices open extra receive windows at scheduled times. In order for the End-device to open its receive window at the scheduled time it receives a time synchronized Beacon from the gateway. This allows the server to know when the end-device is listening.
Bi-directional end-devices with maximal receive slots (Class C): End-devices of Class C have nearly continuously open receive windows, only closed when transmitting. Class C

Posted in Uncategorized | Leave a comment

GSM – Overview

What is GSM?
If you are in Europe or Asia and using a mobile phone, then most probably you are using GSM technology in your mobile phone.

GSM stands for Global System for Mobile Communication. It is a digital cellular technology used for transmitting mobile voice and data services.

The concept of GSM emerged from a cell-based mobile radio system at Bell Laboratories in the early 1970s.

GSM is the name of a standardization group established in 1982 to create a common European mobile telephone standard.

GSM is the most widely accepted standard in telecommunications and it is implemented globally.

GSM is a circuit-switched system that divides each 200 kHz channel into eight 25 kHz time-slots. GSM operates on the mobile communication bands 900 MHz and 1800 MHz in most parts of the world. In the US, GSM operates in the bands 850 MHz and 1900 MHz.

GSM owns a market share of more than 70 percent of the world’s digital cellular subscribers.

GSM makes use of narrowband Time Division Multiple Access (TDMA) technique for transmitting signals.

GSM was developed using digital technology. It has an ability to carry 64 kbps to 120 Mbps of data rates.

Presently GSM supports more than one billion mobile subscribers in more than 210 countries throughout the world.

GSM provides basic to advanced voice and data services including roaming service. Roaming is the ability to use your GSM phone number in another GSM network.

GSM digitizes and compresses data, then sends it down through a channel with two other streams of user data, each in its own timeslot.

Why GSM?
Listed below are the features of GSM that account for its popularity and wide acceptance.

Improved spectrum efficiency

International roaming

Low-cost mobile sets and base stations (BSs)

High-quality speech

Compatibility with Integrated Services Digital Network (ISDN) and other telephone company services

Support for new services

GSM History
The following table shows some of the important events in the rollout of the GSM system.

Years Events
1982 Conference of European Posts and Telegraph (CEPT) establishes a GSM group to widen the standards for a pan-European cellular mobile system.
1985 A list of recommendations to be generated by the group is accepted.
1986 Executed field tests to check the different radio techniques recommended for the air interface.
1987 Time Division Multiple Access (TDMA) is chosen as the access method (with Frequency Division Multiple Access [FDMA]). The initial Memorandum of Understanding (MoU) is signed by telecommunication operators representing 12 countries.
1988 GSM system is validated.
1989 The European Telecommunications Standards Institute (ETSI) was given the responsibility of the GSM specifications.
1990 Phase 1 of the GSM specifications is delivered.
1991 Commercial launch of the GSM service occurs. The DCS1800 specifications are finalized.
1992 The addition of the countries that signed the GSM MoU takes place. Coverage spreads to larger cities and airports.
1993 Coverage of main roads GSM services starts outside Europe.
1994 Data transmission capabilities launched. The number of networks rises to 69 in 43 countries by the end of 1994.
1995 Phase 2 of the GSM specifications occurs. Coverage is extended to rural areas.
1996 June: 133 network in 81 countries operational.
1997 July: 200 network in 109 countries operational, around 44 million subscribers worldwide.
1999 Wireless Application Protocol (WAP) came into existence and became operational in 130 countries with 260 million subscribers.
2000 General Packet Radio Service(GPRS) came into existence.
2001 As of May 2001, over 550 million people were subscribers to mobile telecommunications.
GSM – Architecture
A GSM network comprises of many functional units. These functions and interfaces are explained in this chapter. The GSM network can be broadly divided into:

The Mobile Station (MS)

The Base Station Subsystem (BSS)

The Network Switching Subsystem (NSS)

The Operation Support Subsystem (OSS)

Given below is a simple pictorial view of the GSM architecture.

GSM Architecture
The additional components of the GSM architecture comprise of databases and messaging systems functions:

Home Location Register (HLR)
Visitor Location Register (VLR)
Equipment Identity Register (EIR)
Authentication Center (AuC)
SMS Serving Center (SMS SC)
Gateway MSC (GMSC)
Chargeback Center (CBC)
Transcoder and Adaptation Unit (TRAU)
The following diagram shows the GSM network along with the added elements:

GSM Elements
The MS and the BSS communicate across the Um interface. It is also known as the air interface or the radio link. The BSS communicates with the Network Service Switching (NSS) center across the A interface.

GSM network areas
In a GSM network, the following areas are defined:

Cell : Cell is the basic service area; one BTS covers one cell. Each cell is given a Cell Global Identity (CGI), a number that uniquely identifies the cell.

Location Area : A group of cells form a Location Area (LA). This is the area that is paged when a subscriber gets an incoming call. Each LA is assigned a Location Area Identity (LAI). Each LA is served by one or more BSCs.

MSC/VLR Service Area : The area covered by one MSC is called the MSC/VLR service area.

PLMN : The area covered by one network operator is called the Public Land Mobile Network (PLMN). A PLMN can contain one or more MSCs.

GSM – Specification
The requirements for different Personal Communication Services (PCS) systems differ for each PCS network. Vital characteristics of the GSM specification are listed below:

Modulation
Modulation is the process of transforming the input data into a suitable format for the transmission medium. The transmitted data is demodulated back to its original form at the receiving end. The GSM uses Gaussian Minimum Shift Keying (GMSK) modulation method.

Access Methods
Radio spectrum being a limited resource that is consumed and divided among all the users, GSM devised a combination of TDMA/FDMA as the method to divide the bandwidth among the users. In this process, the FDMA part divides the frequency of the total 25 MHz bandwidth into 124 carrier frequencies of 200 kHz bandwidth.

Each BS is assigned with one or multiple frequencies, and each of this frequency is divided into eight timeslots using a TDMA scheme. Each of these slots are used for both transmission as well as reception of data. These slots are separated by time so that a mobile unit doesn’t transmit and receive data at the same time.

Transmission Rate
The total symbol rate for GSM at 1 bit per symbol in GMSK produces 270.833 K symbols/second. The gross transmission rate of a timeslot is 22.8 Kbps.

GSM is a digital system with an over-the-air bit rate of 270 kbps.

Frequency Band
The uplink frequency range specified for GSM is 933 – 960 MHz (basic 900 MHz band only). The downlink frequency band 890 – 915 MHz (basic 900 MHz band only).

Channel Spacing
Channel spacing indicates the spacing between adjacent carrier frequencies. For GSM, it is 200 kHz.

Speech Coding
For speech coding or processing, GSM uses Linear Predictive Coding (LPC). This tool compresses the bit rate and gives an estimate of the speech parameters. When the audio signal passes through a filter, it mimics the vocal tract. Here, the speech is encoded at 13 kbps.

Duplex Distance
Duplex distance is the space between the uplink and downlink frequencies. The duplex distance for GSM is 80 MHz, where each channel has two frequencies that are 80 MHz apart.

Misc
Frame duration : 4.615 mS

Duplex Technique : Frequency Division Duplexing (FDD) access mode previously known as WCDMA.

Speech channels per RF channel : 8.

GSM – Addresses and Identifiers
GSM treats the users and the equipment in different ways. Phone numbers, subscribers, and equipment identifiers are some of the known ones. There are many other identifiers that have been well-defined, which are required for the subscriber’s mobility management and for addressing the remaining network elements. Vital addresses and identifiers that are used in GSM are addressed below.

International Mobile Station Equipment Identity (IMEI)
The International Mobile Station Equipment Identity (IMEI) looks more like a serial number which distinctively identifies a mobile station internationally. This is allocated by the equipment manufacturer and registered by the network operator, who stores it in the Entrepreneurs-in-Residence (EIR). By means of IMEI, one recognizes obsolete, stolen, or non-functional equipment.

Following are the parts of IMEI:

Type Approval Code (TAC) : 6 decimal places, centrally assigned.

Final Assembly Code (FAC) : 6 decimal places, assigned by the manufacturer.

Serial Number (SNR) : 6 decimal places, assigned by the manufacturer.

Spare (SP) : 1 decimal place.

Thus, IMEI = TAC + FAC + SNR + SP. It uniquely characterizes a mobile station and gives clues about the manufacturer and the date of manufacturing.

International Mobile Subscriber Identity (IMSI)
Every registered user has an original International Mobile Subscriber Identity (IMSI) with a valid IMEI stored in their Subscriber Identity Module (SIM).

IMSI comprises of the following parts:

Mobile Country Code (MCC) : 3 decimal places, internationally standardized.

Mobile Network Code (MNC) : 2 decimal places, for unique identification of mobile network within the country.

Mobile Subscriber Identification Number (MSIN) : Maximum 10 decimal places, identification number of the subscriber in the home mobile network.

Mobile Subscriber ISDN Number (MSISDN)
The authentic telephone number of a mobile station is the Mobile Subscriber ISDN Number (MSISDN). Based on the SIM, a mobile station can have many MSISDNs, as each subscriber is assigned with a separate MSISDN to their SIM respectively.

Listed below is the structure followed by MSISDN categories, as they are defined based on international ISDN number plan:

Country Code (CC) : Up to 3 decimal places.

National Destination Code (NDC) : Typically 2-3 decimal places.

Subscriber Number (SN) : Maximum 10 decimal places.

Mobile Station Roaming Number (MSRN)
Mobile Station Roaming Number (MSRN) is an interim location dependent ISDN number, assigned to a mobile station by a regionally responsible Visitor Location Register (VLA). Using MSRN, the incoming calls are channelled to the MS.

The MSRN has the same structure as the MSISDN.

Country Code (CC) : of the visited network.

National Destination Code (NDC) : of the visited network.

Subscriber Number (SN) : in the current mobile network.

Location Area Identity (LAI)
Within a PLMN, a Location Area identifies its own authentic Location Area Identity (LAI). The LAI hierarchy is based on international standard and structured in a unique format as mentioned below:

Country Code (CC) : 3 decimal places.

Mobile Network Code (MNC) : 2 decimal places.

Location Area Code (LAC) : maximum 5 decimal places or maximum twice 8 bits coded in hexadecimal (LAC < FFFF).

Temporary Mobile Subscriber Identity (TMSI)
Temporary Mobile Subscriber Identity (TMSI) can be assigned by the VLR, which is responsible for the current location of a subscriber. The TMSI needs to have only local significance in the area handled by the VLR. This is stored on the network side only in the VLR and is not passed to the Home Location Register (HLR).

Together with the current location area, the TMSI identifies a subscriber uniquely. It can contain up to 4 × 8 bits.

Local Mobile Subscriber Identity (LMSI)
Each mobile station can be assigned with a Local Mobile Subscriber Identity (LMSI), which is an original key, by the VLR. This key can be used as the auxiliary searching key for each mobile station within its region. It can also help accelerate the database access. An LMSI is assigned if the mobile station is registered with the VLR and sent to the HLR. LMSI comprises of four octets (4×8 bits).

Cell Identifier (CI)
Using a Cell Identifier (CI) (maximum 2 × 8) bits, the individual cells that are within an LA can be recognized. When the Global Cell Identity (LAI + CI) calls are combined, then it is uniquely defined.

GSM – Operations
Once a Mobile Station initiates a call, a series of events takes place. Analyzing these events can give an insight into the operation of the GSM system.

Mobile Phone to Public Switched Telephone Network (PSTN)
When a mobile subscriber makes a call to a PSTN telephone subscriber, the following sequence of events takes place:

The MSC/VLR receives the message of a call request.

The MSC/VLR checks if the mobile station is authorized to access the network. If so, the mobile station is activated. If the mobile station is not authorized, then the service will be denied.

MSC/VLR analyzes the number and initiates a call setup with the PSTN.

MSC/VLR asks the corresponding BSC to allocate a traffic channel (a radio channel and a time slot).

The BSC allocates the traffic channel and passes the information to the mobile station.

The called party answers the call and the conversation takes place.

The mobile station keeps on taking measurements of the radio channels in the present cell and the neighbouring cells and passes the information to the BSC. The BSC decides if a handover is required. If so, a new traffic channel is allocated to the mobile station and the handover takes place. If handover is not required, the mobile station continues to transmit in the same frequency.

PSTN to Mobile Phone
When a PSTN subscriber calls a mobile station, the following sequence of events takes place:

The Gateway MSC receives the call and queries the HLR for the information needed to route the call to the serving MSC/VLR.

The GMSC routes the call to the MSC/VLR.

The MSC checks the VLR for the location area of the MS.

The MSC contacts the MS via the BSC through a broadcast message, that is, through a paging request.

The MS responds to the page request.

The BSC allocates a traffic channel and sends a message to the MS to tune to the channel. The MS generates a ringing signal and, after the subscriber answers, the speech connection is established.

Handover, if required, takes place, as discussed in the earlier case.

To transmit the speech over the radio channel in the stipulated time, the MS codes it at the rate of 13 Kbps. The BSC transcodes the speech to 64 Kbps and sends it over a land link or a radio link to the MSC. The MSC then forwards the speech data to the PSTN. In the reverse direction, the speech is received at 64 Kbps at the BSC and the BSC transcodes it to 13 Kbps for radio transmission.

GSM supports 9.6 Kbps data that can be channelled in one TDMA timeslot. To supply higher data rates, many enhancements were done to the GSM standards (GSM Phase 2 and GSM Phase 2+).

GSM – Protocol Stack
GSM architecture is a layered model that is designed to allow communications between two different systems. The lower layers assure the services of the upper-layer protocols. Each layer passes suitable notifications to ensure the transmitted data has been formatted, transmitted, and received accurately.

The GMS protocol stacks diagram is shown below:

GSM Protocol Stack
MS Protocols
Based on the interface, the GSM signaling protocol is assembled into three general layers:

Layer 1 : The physical layer. It uses the channel structures over the air interface.

Layer 2 : The data-link layer. Across the Um interface, the data-link layer is a modified version of the Link access protocol for the D channel (LAP-D) protocol used in ISDN, called Link access protocol on the Dm channel (LAP-Dm). Across the A interface, the Message Transfer Part (MTP), Layer 2 of SS7 is used.

Layer 3 : GSM signalling protocol’s third layer is divided into three sublayers:

Radio Resource Management (RR),
Mobility Management (MM), and
Connection Management (CM).
MS to BTS Protocols
The RR layer is the lower layer that manages a link, both radio and fixed, between the MS and the MSC. For this formation, the main components involved are the MS, BSS, and MSC. The responsibility of the RR layer is to manage the RR-session, the time when a mobile is in a dedicated mode, and the radio channels including the allocation of dedicated channels.

The MM layer is stacked above the RR layer. It handles the functions that arise from the mobility of the subscriber, as well as the authentication and security aspects. Location management is concerned with the procedures that enable the system to know the current location of a powered-on MS so that incoming call routing can be completed.

The CM layer is the topmost layer of the GSM protocol stack. This layer is responsible for Call Control, Supplementary Service Management, and Short Message Service Management. Each of these services are treated as individual layer within the CM layer. Other functions of the CC sublayer include call establishment, selection of the type of service (including alternating between services during a call), and call release.

BSC Protocols
The BSC uses a different set of protocols after receiving the data from the BTS. The Abis interface is used between the BTS and BSC. At this level, the radio resources at the lower portion of Layer 3 are changed from the RR to the Base Transceiver Station Management (BTSM). The BTS management layer is a relay function at the BTS to the BSC.

The RR protocols are responsible for the allocation and reallocation of traffic channels between the MS and the BTS. These services include controlling the initial access to the system, paging for MT calls, the handover of calls between cell sites, power control, and call termination. The BSC still has some radio resource management in place for the frequency coordination, frequency allocation, and the management of the overall network layer for the Layer 2 interfaces.

To transit from the BSC to the MSC, the BSS mobile application part or the direct application part is used, and SS7 protocols is applied by the relay, so that the MTP 1-3 can be used as the prime architecture.

MSC Protocols
At the MSC, starting from the BSC, the information is mapped across the A interface to the MTP Layers 1 through 3. Here, Base Station System Management Application Part (BSS MAP) is said to be the equivalent set of radio resources. The relay process is finished by the layers that are stacked on top of Layer 3 protocols, they are BSS MAP/DTAP, MM, and CM. This completes the relay process. To find and connect to the users across the network, MSCs interact using the control-signalling network. Location registers are included in the MSC databases to assist in the role of determining how and whether connections are to be made to roaming users.

Each GSM MS user is given a HLR that in turn comprises of the user’s location and subscribed services. VLR is a separate register that is used to track the location of a user. When the users move out of the HLR covered area, the VLR is notified by the MS to find the location of the user. The VLR in turn, with the help of the control network, signals the HLR of the MS’s new location. With the help of location information contained in the user’s HLR, the MT calls can be routed to the user.

GSM – User Services
GSM offers much more than just voice telephony. Contact your local GSM network operator to the specific services that you can avail.

GSM offers three basic types of services:

Telephony services or teleservices
Data services or bearer services
Supplementary services
Teleservices
The abilities of a Bearer Service are used by a Teleservice to transport data. These services are further transited in the following ways:

Voice Calls
The most basic Teleservice supported by GSM is telephony. This includes full-rate speech at 13 kbps and emergency calls, where the nearest emergency-service provider is notified by dialing three digits.

Videotext and Facsmile
Another group of teleservices includes Videotext access, Teletex transmission, Facsimile alternate speech and facsimile Group 3, Automatic facsimile Group, 3 etc.

Short Text Messages
Short Messaging Service (SMS) service is a text messaging service that allows sending and receiving text messages on your GSM mobile phone. In addition to simple text messages, other text data including news, sports, financial, language, and location-based data can also be transmitted.

Bearer Services
Data services or Bearer Services are used through a GSM phone. to receive and send data is the essential building block leading to widespread mobile Internet access and mobile data transfer. GSM currently has a data transfer rate of 9.6k. New developments that will push up data transfer rates for GSM users are HSCSD (high speed circuit switched data) and GPRS (general packet radio service) are now available.

Supplementary Services
Supplementary services are additional services that are provided in addition to teleservices and bearer services. These services include caller identification, call forwarding, call waiting, multi-party conversations, and barring of outgoing (international) calls, among others. A brief description of supplementary services is given here:

Conferencing : It allows a mobile subscriber to establish a multiparty conversation, i.e., a simultaneous conversation between three or more subscribers to setup a conference call. This service is only applicable to normal telephony.

Call Waiting : This service notifies a mobile subscriber of an incoming call during a conversation. The subscriber can answer, reject, or ignore the incoming call.

Call Hold : This service allows a subscriber to put an incoming call on hold and resume after a while. The call hold service is applicable to normal telephony.

Call Forwarding : Call Forwarding is used to divert calls from the original recipient to another number. It is normally set up by the subscriber himself. It can be used by the subscriber to divert calls from the Mobile Station when the subscriber is not available, and so to ensure that calls are not lost.

Call Barring : Call Barring is useful to restrict certain types of outgoing calls such as ISD or stop incoming calls from undesired numbers. Call barring is a flexible service that enables the subscriber to conditionally bar calls.

Number Identification : There are following supplementary services related to number identification:

Calling Line Identification Presentation : This service displays the telephone number of the calling party on your screen.

Calling Line Identification Restriction : A person not wishing their number to be presented to others subscribes to this service.

Connected Line Identification Presentation : This service is provided to give the calling party the telephone number of the person to whom they are connected. This service is useful in situations such as forwarding's where the number connected is not the number dialled.

Connected Line Identification Restriction : There are times when the person called does not wish to have their number presented and so they would subscribe to this person. Normally, this overrides the presentation service.

Malicious Call Identification : The malicious call identification service was provided to combat the spread of obscene or annoying calls. The victim should subscribe to this service, and then they could cause known malicious calls to be identified in the GSM network, using a simple command.

Advice of Charge (AoC) : This service was designed to give the subscriber an indication of the cost of the services as they are used. Furthermore, those service providers who wish to offer rental services to subscribers without their own SIM can also utilize this service in a slightly different form. AoC for data calls is provided on the basis of time measurements.

Closed User Groups (CUGs) : This service is meant for groups of subscribers who wish to call only each other and no one else.

Unstructured supplementary services data (USSD) : This allows operator-defined individual services.

GSM – Security and Encryption
GSM is the most secured cellular telecommunications system available today. GSM has its security methods standardized. GSM maintains end-to-end security by retaining the confidentiality of calls and anonymity of the GSM subscriber.

Temporary identification numbers are assigned to the subscriber’s number to maintain the privacy of the user. The privacy of the communication is maintained by applying encryption algorithms and frequency hopping that can be enabled using digital systems and signalling.

This chapter gives an outline of the security measures implemented for GSM subscribers.

Mobile Station Authentication
The GSM network authenticates the identity of the subscriber through the use of a challenge-response mechanism. A 128-bit Random Number (RAND) is sent to the MS. The MS computes the 32-bit Signed Response (SRES) based on the encryption of the RAND with the authentication algorithm (A3) using the individual subscriber authentication key (Ki). Upon receiving the SRES from the subscriber, the GSM network repeats the calculation to verify the identity of the subscriber.

The individual subscriber authentication key (Ki) is never transmitted over the radio channel, as it is present in the subscriber's SIM, as well as the AUC, HLR, and VLR databases. If the received SRES agrees with the calculated value, the MS has been successfully authenticated and may continue. If the values do not match, the connection is terminated and an authentication failure is indicated to the MS.

The calculation of the signed response is processed within the SIM. It provides enhanced security, as confidential subscriber information such as the IMSI or the individual subscriber authentication key (Ki) is never released from the SIM during the authentication process.

Signalling and Data Confidentiality
The SIM contains the ciphering key generating algorithm (A8) that is used to produce the 64-bit ciphering key (Kc). This key is computed by applying the same random number (RAND) used in the authentication process to ciphering key generating algorithm (A8) with the individual subscriber authentication key (Ki).

GSM provides an additional level of security by having a way to change the ciphering key, making the system more resistant to eavesdropping. The ciphering key may be changed at regular intervals as required. As in case of the authentication process, the computation of the ciphering key (Kc) takes place internally within the SIM. Therefore, sensitive information such as the individual subscriber authentication key (Ki) is never revealed by the SIM.

Encrypted voice and data communications between the MS and the network is accomplished by using the ciphering algorithm A5. Encrypted communication is initiated by a ciphering mode request command from the GSM network. Upon receipt of this command, the mobile station begins encryption and decryption of data using the ciphering algorithm (A5) and the ciphering key (Kc).

Subscriber Identity Confidentiality
To ensure subscriber identity confidentiality, the Temporary Mobile Subscriber Identity (TMSI) is used. Once the authentication and encryption procedures are done, the TMSI is sent to the mobile station. After the receipt, the mobile station responds. The TMSI is valid in the location area in which it was issued. For communications outside the location area, the Location Area Identification (LAI) is necessary in addition to the TMSI.

GSM – Billing
GSM service providers are doing billing based on the services they are providing to their customers. All the parameters are simple enough to charge a customer for the provided services.

This chapter provides an overview of the frequently used billing techniques and parameters applied to charge a GSM subscriber.

Telephony Service
These services can be charged on per call basis. The call initiator has to pay the charges, and the incoming calls are nowadays free. A customer can be charged based on different parameters such as:

International call or long distance call.
Local call.
Call made during peak hours.
Call made during night time.
Discounted call during weekends.
Call per minute or per second.
Many more other criteria can be designed by a service provider to charge their customers.
SMS Service
Most of the service providers charge their customer's SMS services based on the number of text messages sent. There are other prime SMS services available where service providers charge more than normal SMS charge. These services are being availed in collaboration of Television Networks or Radio Networks to demand SMS from the audiences.

Most of the time, the charges are paid by the SMS sender but for some services like stocks and share prices, mobile banking facilities, and leisure booking services, etc. the recipient of the SMS has to pay for the service.

GPRS Services
Using GPRS service, you can browse, play games on the Internet, and download movies. So a service provider will charge you based on the data uploaded as well as data downloaded on your mobile phone. These charges will be based on per Kilo Byte data downloaded/uploaded.

Additional parameter could be a QoS provided to you. If you want to watch a movie, then a low QoS may work because some data loss may be acceptable, but if you are downloading a zip file, then a single byte loss will corrupt your complete downloaded file.

Another parameter could be peak and off peak time to download a data file or to browse the Internet.

Supplementary Services
Most of the supplementary services are being provided based on monthly rental or absolutely free. For example, call waiting, call forwarding, calling number identification, and call on hold are available at zero cost.

Call barring is a service, which service providers use just to recover their dues, etc., otherwise this service is not being used by any subscriber.

Call conferencing service is a form of simple telephone call where the customers are charged for multiple calls made at a time. No service provider charges extra charge for this service.

Closed User Group (CUG) is very popular and is mainly being used to give special discounts to the users if they are making calls to a particular defined group of subscribers.

Advice of Charge (AoC) can be charged based on number of queries made by a subscriber.

Posted in Uncategorized | Leave a comment

GSM Module Interfacing and commands

GSM Module Interfacing

GSM module is used in many communication devices which are based on GSM (Global System for Mobile Communications) technology. It is used to interact with GSM network using a computer. GSM module only understands AT commands, and can respond accordingly. The most basic command is “AT”, if GSM respond OK then it is working good otherwise it respond with “ERROR”. There are various AT commands like ATA for answer a call, ATD to dial a call, AT+CMGR to read the message, AT+CMGS to send the sms etc. AT commands should be followed by Carriage return i.e. \r (0D in hex), like “AT+CMGS\r”. We can use GSM module using these commands.

GSM Interfacing with 8051

Instead of using PC, we can use microcontrollers to interact with GSM module and LCD to get the response from GSM module. So we are going to interface GSM with a 8051 microcontroller (AT89S52). It’s very easy to interface GSM with 8051, we just need to send AT commands from microcontroller and receive response from GSM and display it on LCD. We can use microcontroller’s serial port to communicate with GSM, means using PIN 10 (RXD) and 11 (TXD).
GSM Module SIM900A

First we need to connect LCD to 8051, you can learn this from here: LCD Interfacing with 8051 Microcontroller. Then we need to connect GSM module to 8051, now here we should pay some attention. First you need to check that whether your GSM module is capable of working at TTL logic or it can only work with RS232. Basically if your module has RX and TX (with GND) Pins on board then it can work on TTL logic. And If it don’t have any RX,TX pins and only have a RS232 port (serial port with 9) then you need to use MAX232 IC to connect serial port to the microcontroller. Basically MAX232 used to convert serial data into TTL logic because Microcontroller can only work on TTL logic. But if GSM module has RX, TX pins then you don’t need to use MAX232 or any serial converter, you can directly connect RX of GSM to TX (PIN 11) of 8051 and TX of GSM to RX (PIN 10) of 8051. In our case I have used SIM900A module and it has RX, TX pins so I haven’t used MAX232.
Circuit Diagram for GSM Interfacing with 8051 Microcontroller

Circuit Diagram for GSM interfacing with AT89S52 microcontroller is shown in above figure. Now after the connection, we just need to write program to send AT commands to GSM and receive its response on LCD. There are many AT commands as described above, but our scope of this article is just to interface GSM with 8051, so we are just going to send command “AT” followed by “\r” (0D in hex). This will give us a response “OK”. But you can extend this program to use all the facilities of GSM.

Code explanation

Besides all the LCD related functions, here we have used Serial port and timer mode register (TMOD). You can learn about LCD functions and other code by going through our 8051 projects section, here I am explaining about serial communication related code functions:

GSM_init() function:

This function is use to set the Baudrate for microcontroller. Baudrate is nothing but the Bits/second transmitted or received. And we need to match the baudrate of 8051 to the Baud rate of GSM module i.e. 9600. We have used the Timer 1 in Mode 2 (8-bit auto-reload mode) by setting the TMOD register to 0X20 and Higher byte of Timer 1(TH1) to 0XFD to get the baud rate of 9600. Also SCON register is used to set the mode of serial communication, we have used Mode1 (8-bit UART) with receiving enabled.

GSM_write Function:

SBUF (serial buffer special function register) is used for serial communication, whenever we want to send any byte to serial device we put that byte in SBUF register, when the complete byte has been sent then TI bit is set by hardware. We need to reset it for sending next byte. It’s a flag that indicates that byte has been sent successfully. TI is the second bit of SCON register. We have sent “AT” using this function.

GSM_read function:

Same as sending, whenever we receive any byte from external device that byte is put in SBUF register, we just need to read it. And whenever the complete byte has been received RI bit is set by hardware. We need to reset it for receiving next byte. RI is the first bit of SCON register. We have read response “OK” using this function.

Code:

#include
#define display_port P2 //Data pins connected to port 2 on microcontroller
sbit rs = P3^2; //RS pin connected to pin 2 of port 3
sbit rw = P3^3; // RW pin connected to pin 3 of port 3
sbit e = P3^4; //E pin connected to pin 4 of port 3
int k;
unsigned char str[26];
void GSM_init() // serial port initialization
{
TMOD=0×20; // Timer 1 selected, Mode 2(8-bit auto-reload mode)
TH1=0xfd; // 9600 baudrate
SCON=0×50; // Mode 1(8-bit UART), receiving enabled
TR1=1; // Start timer
}
void msdelay(unsigned int time) // Function for creating delay in milliseconds.
{
unsigned m,n ;
for(m=0;m<time;m++)
for(n=0;n<1275;n++);
}
void lcd_cmd(unsigned char command) //Function to send command instruction to LCD
{
display_port = command;
rs= 0;
rw=0;
e=1;
msdelay(1);
e=0;
}
void lcd_data(unsigned char disp_data) //Function to send display data to LCD
{
display_port = disp_data;
rs= 1;
rw=0;
e=1;
msdelay(1);
e=0;
}
void lcd_init() //Function to prepare the LCD and get it ready
{
lcd_cmd(0×38); // for using 2 lines and 5X7 matrix of LCD
msdelay(10);
lcd_cmd(0x0F); // turn display ON, cursor blinking
msdelay(10);
lcd_cmd(0×01); //clear screen
msdelay(10);
lcd_cmd(0×80); // bring cursor to beginning of first line
msdelay(10);
}
void lcd_string(unsigned char *str) // Function to display string on LCD
{
int i=0;
while(str[i]!='')
{
lcd_data(str[i]);
i++;
msdelay(10);
if(i==15) lcd_cmd(0xc2);
}
return;
}
void GSM_write(unsigned char ch) // Function to send commands to GSM
{
SBUF=ch; // Put byte in SBUF to send to GSM
while(TI==0); //wait until the byte trasmission
TI=0; //clear TI to send next byte.
}
void GSM_read() // Function to read the response from GSM
{
while(RI==0); // Wait until the byte received
str[k]=SBUF; //storing byte in str array
RI=0; //clear RI to receive next byte
}

void main()
{
k=0;
lcd_init();
GSM_init();
msdelay(200);
lcd_string("Interfacing GSM with 8051");
msdelay(200);
lcd_cmd(0×01); // Clear LCD screen
msdelay(10);
GSM_write('A'); // Sending 'A' to GSM module
lcd_data('A');
msdelay(1);
GSM_write('T'); // Sending 'T' to GSM module
lcd_data('T');
msdelay(1);
GSM_write(0x0d); // Sending carriage return to GSM module
msdelay(50);
while(1)
{
GSM_read();
if(str[k-1]=='O' && str[k]=='K'){
lcd_data(0×20); // Write 'Space'
lcd_data(str[k-1]);
lcd_data(str[k]);
break;
}
k=k+1;
}
}

Posted in Uncategorized | Leave a comment

U-Boot’s bring-up

Even though unnecessary in most cases, it’s sometimes desired to modify U-Boot’s own bring-up process, in particular for initializing custom hardware during early stages. This section explains the basics of this part of U-Boot.

U-Boot is one of the first things to run on the processor, and may be responsible for the most basic hardware initialization. On some platforms the processor’s RAM isn’t configured when U-Boot starts running, so the underlying assumption is that U-Boot may run directly from ROM (typically flash memory).

The bring-up process’ key event is hence when U-Boot copies itself from where it runs in the beginning into RAM, from which it runs the more sophisticated tasks (handling boot commands in particular). This self-copy is referred to as “relocation”.

Almost needless to say, the processor runs in “real mode”: The MMU, if there is one, is off. There is no memory translation nor protection. U-Boot plays a few dirty tricks based on this.

In gross terms, the U-Boot loader runs through the following phases:

Pre-relocation initialization (possibly directly from flash or other kind of ROM)
Relocation: Copy the code to RAM.
Post-relocation initialization (from proper RAM).
Execution of commands: Through autoboot or console shell
Passing control to the Linux kernel (or other target application)
Note that in several scenarios, U-Boot starts from proper RAM to begin with, and consequently there is no actual relocation taking place. The division into pre-relocation and post-relocation becomes somewhat artificial in these scenarios, yet this is the terminology.

Posted in Uncategorized | Leave a comment

U-boot

U-Boot is an open source Universal Boot Loader that is frequently used in the Linux community. Xilinx provides a Git tree located at https://github.com/Xilinx/u-boot-xlnx which includes U-Boot to run on Xilinx boards. The Xilinx U-Boot project is based on the source code from http://git.denx.de.

U-Boot Commands
The list of U-Boot commands can be accessed while in the U-Boot prompt. Type “help” or “?” for a complete listing of available commands. Below an example is given:

? – alias for ‘help’
base – print or set address offset
bdinfo – print Board Info structure
boot – boot default, i.e., run ‘bootcmd’
bootd – boot default, i.e., run ‘bootcmd’
bootm – boot application image from memory
bootp – boot image via network using BOOTP/TFTP protocol
cmp – memory compare
coninfo – print console devices and information
cp – memory copy
crc32 – checksum calculation
date – get/set/reset date & time
echo – echo args to console
editenv – edit environment variable
erase – erase FLASH memory
ext2load- load binary file from a Ext2 filesystem
ext2ls – list files in a directory (default /)
fatinfo – print information about filesystem
fatload – load binary file from a dos filesystem
fatls – list files in a directory (default /)
fdt – flattened device tree utility commands
flinfo – print FLASH memory information
go – start application at address ‘addr’
help – print command description/usage
iminfo – print header information for application image
imls – list all images found in flash
imxtract- extract a part of a multi-image
itest – return true/false on integer compare
loadb – load binary file over serial line (kermit mode)
loads – load S-Record file over serial line
loady – load binary file over serial line (ymodem mode)
loop – infinite loop on address range
md – memory display
mm – memory modify (auto-incrementing address)
mmc – MMC sub system
mmcinfo – display MMC info
mtest – simple RAM read/write test
mw – memory write (fill)
nfs – boot image via network using NFS protocol
nm – memory modify (constant address)
ping – send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect – enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reset – Perform RESET of the CPU
run – run commands in an environment variable
setenv – set environment variables
sf – SPI flash sub-system
sleep – delay execution for some time
source – run script from memory
sspi – SPI utility commands
tftpboot- boot image via network using TFTP protocol
version – print monitor version

Programming QSPI Flash

U-Boot provides the SF command to program serial flash devices. On the ZC702 board you can use the SF command to program a QSPI device. Here is an example of loading an image file to QSPI device.
uboot> sf
Usage:
sf probe [[bus:]cs] [hz] [mode] – init flash device on given SPI bus and chip select
sf read addr offset len – read ‘len’ bytes starting at ‘offset’ to memory at ‘addr’
sf write addr offset len – write ‘len’ bytes from memory at ‘addr’ to flash at ‘offset’
sf erase offset [+]len – erase ‘len’ bytes from ‘offset’; ‘+len’ round up ‘len’ to block size
sf update addr offset len – erase and write ‘len’bytes from memory at ‘addr’ to flash at ‘offset

uboot> sf probe 0 0 0
SF: Detected N25Q128 with page size 256, total 16 MiB
16384 KiB N25Q128 at 0:0 is now current device

// Detect QSPI Flash parameters
// To make QSPI clock run faster, higher speed can be set to second parameter,
// e.g. setting QSPI clock to 20MHz
// sf probe 0 20000000 0

uboot> sf erase 0 0×200000

// Erase 2MB from QSPI offset 0×0
// Note: If erase size is less than QSPI Flash page size, u-boot reports erase error

uboot> sf read 0×08000000 0 100

// Read QSPI Flash from 0×0 to DDR 0×08000000 with 100 bytes
// you can use any location in DDR as destination. make sure it doesnt overwrite u-boot
// code/data area. u-boot is at 0×04000000.

uboot> md 08000000
08000000: ffffffff ffffffff ffffffff ffffffff …………….

// Display content in memory 0×08000000.
// U-boot by default uses hex

// load the boot image to DDR
// load method can be KERMIT through UART, XMD dow -data through JTAG, TFTP through Ethernet
// or read from SD Card directly

zynq-boot> loadb 0×08000000

// load the boot image through KERMIT protocol after this step
// it is assumed that you should have a boot image generated using the bootgen utility

## Ready for binary (kermit) download to 0×08000000 at 115200 bps…
## Total Size = 0x0003e444 = 255044 Bytes
## Start Addr = 0×08000000
uboot> md 08000000 100

uboot> sf write 0×08000000 0 0x3E444

// Write from DDR address 0×08000000 to QSPI offset 0 with 0x3E444 bytes of data

// U-Boot read command can be used to see what is programmed in to QSPI memory.
// Following is the syntax of the “sf read” command.

zynq-boot> sf read

NOTE: The “destination address” should not be ZERO.

Example:

uboot> sf read 0×800 0×0 0×2000

Programming NAND Flash
U-Boot provides the nand command to program nand devices. Here is an example of loading an image file to nand device. The command sequence for nand is same as QSPI except the commands.Below nand command sequence for writing an image to nand device. The read command at the end just to ensure the data was written properly and you can use cmp command for comparing written data with original data which was lready present in DDR..
nand info
nand erase

// Download the image to a location DDR(DDR addr) using tftp and then perform write to nand from that DDR address as shown below.

nand write

// The nand programming was done wuith the above command but to ensure that it has written successfully just read the written data using the below read command.
// Provide DDR addr different from the above and differ from the above DDR addr at least by the so that we can compare both using cmp command and ensure it was written successfully.

nand read

Programming NOR Flash
U-Boot uses the regular memory command to program NOR devices. Here is command sequence of loading an image file to NOR device.
flinfo
erase all
cp.b .
Authentication and Decryption in zynq u-boot
Zynq U-boot can authenticate and decrypt the partitions before loading them for execution. u-boot initially loads the image to a location to DDR. Then this DDR location was passed as an argument to command “zynqrsa ” . The whole functionality was implemented under this command so that user can load image to DDR from tftp or anything and then user can provide that address for authenticating that image and then loading that.

The zynqrsa command authenticates or decrypts or both authenticate and decrypt the images and loads to DDR. The image has to be generated using bootgen with proper authentication and encryption keys. The zynq rsa command authenticates or decrypts only the images in which partition owner is mentioned as u-boot while preparing images using bootgen. This will enabled only if we enable the config “CONFIG_CMD_ZYNQ_RSA”. This config also enables the decryption functionality. The Decryption process can also invoked using the command “zynqaes ”. For more details check zynqaes help..

U-Boot 14.3 (and newer releases) Specific Details
U-Boot is now by default expecting a uImage Linux kernel image and a ramdisk that is also wrapped with the mkimage utility. It is using the bootm command by default now which also passes the address of the device tree to the Linux kernel. The Linux build process will build a uImage when the uImage target is specified on the make command line.

Mkimage Utility
The mkimage utility is part of U-Boot and is placed in the u-boot/tools directory during the build process. It is used to prepend a header onto the specified image such that U-Boot can verify an image was loaded into memory correctly.

Bootm Command Details
The bootm command has the following format:
bootm
The following U-Boot commands illustrate loading the Linux kernel uImage, a mkimage wrapped ramdisk, and a device tree into memory from the SD card and then booting the Linux kernel.
u-boot> fatload mmc 0 0×3000000 uImage
u-boot> fatload mmc 0 0x2A00000 devicetree.dtb
u-boot> fatload mmc 0 0×2000000 uramdisk.image.gz
u-boot> bootm 0×3000000 0×2000000 0x2A00000
With the bootm command, U-Boot is relocating the images before it boots Linux such that the addresses above may not be what the kernel sees. U-Boot also alters the device tree to tell the kernel where the ramdisk image is located in memory (initrd-start and initrd-end). The bootm command sets the r2 register to the address of the device tree in memory which is not done by the go command.

Posted in Uncategorized | Leave a comment

Linux and the Device Tree

Linux and the Device Tree
————————-
The Linux usage model for device tree data

Author: Grant Likely

This article describes how Linux uses the device tree. An overview of
the device tree data format can be found on the device tree usage page
at devicetree.org[1].

[1] http://devicetree.org/Device_Tree_Usage

The “Open Firmware Device Tree”, or simply Device Tree (DT), is a data
structure and language for describing hardware. More specifically, it
is a description of hardware that is readable by an operating system
so that the operating system doesn’t need to hard code details of the
machine.

Structurally, the DT is a tree, or acyclic graph with named nodes, and
nodes may have an arbitrary number of named properties encapsulating
arbitrary data. A mechanism also exists to create arbitrary
links from one node to another outside of the natural tree structure.

Conceptually, a common set of usage conventions, called ‘bindings’,
is defined for how data should appear in the tree to describe typical
hardware characteristics including data busses, interrupt lines, GPIO
connections, and peripheral devices.

As much as possible, hardware is described using existing bindings to
maximize use of existing support code, but since property and node
names are simply text strings, it is easy to extend existing bindings
or create new ones by defining new nodes and properties. Be wary,
however, of creating a new binding without first doing some homework
about what already exists. There are currently two different,
incompatible, bindings for i2c busses that came about because the new
binding was created without first investigating how i2c devices were
already being enumerated in existing systems.

1. History
———-
The DT was originally created by Open Firmware as part of the
communication method for passing data from Open Firmware to a client
program (like to an operating system). An operating system used the
Device Tree to discover the topology of the hardware at runtime, and
thereby support a majority of available hardware without hard coded
information (assuming drivers were available for all devices).

Since Open Firmware is commonly used on PowerPC and SPARC platforms,
the Linux support for those architectures has for a long time used the
Device Tree.

In 2005, when PowerPC Linux began a major cleanup and to merge 32-bit
and 64-bit support, the decision was made to require DT support on all
powerpc platforms, regardless of whether or not they used Open
Firmware. To do this, a DT representation called the Flattened Device
Tree (FDT) was created which could be passed to the kernel as a binary
blob without requiring a real Open Firmware implementation. U-Boot,
kexec, and other bootloaders were modified to support both passing a
Device Tree Binary (dtb) and to modify a dtb at boot time. DT was
also added to the PowerPC boot wrapper (arch/powerpc/boot/*) so that
a dtb could be wrapped up with the kernel image to support booting
existing non-DT aware firmware.

Some time later, FDT infrastructure was generalized to be usable by
all architectures. At the time of this writing, 6 mainlined
architectures (arm, microblaze, mips, powerpc, sparc, and x86) and 1
out of mainline (nios) have some level of DT support.

2. Data Model
————-
If you haven’t already read the Device Tree Usage[1] page,
then go read it now. It’s okay, I’ll wait….

2.1 High Level View
——————-
The most important thing to understand is that the DT is simply a data
structure that describes the hardware. There is nothing magical about
it, and it doesn’t magically make all hardware configuration problems
go away. What it does do is provide a language for decoupling the
hardware configuration from the board and device driver support in the
Linux kernel (or any other operating system for that matter). Using
it allows board and device support to become data driven; to make
setup decisions based on data passed into the kernel instead of on
per-machine hard coded selections.

Ideally, data driven platform setup should result in less code
duplication and make it easier to support a wide range of hardware
with a single kernel image.

Linux uses DT data for three major purposes:
1) platform identification,
2) runtime configuration, and
3) device population.

2.2 Platform Identification
—————————
First and foremost, the kernel will use data in the DT to identify the
specific machine. In a perfect world, the specific platform shouldn’t
matter to the kernel because all platform details would be described
perfectly by the device tree in a consistent and reliable manner.
Hardware is not perfect though, and so the kernel must identify the
machine during early boot so that it has the opportunity to run
machine-specific fixups.

In the majority of cases, the machine identity is irrelevant, and the
kernel will instead select setup code based on the machine’s core
CPU or SoC. On ARM for example, setup_arch() in
arch/arm/kernel/setup.c will call setup_machine_fdt() in
arch/arm/kernel/devtree.c which searches through the machine_desc
table and selects the machine_desc which best matches the device tree
data. It determines the best match by looking at the ‘compatible’
property in the root device tree node, and comparing it with the
dt_compat list in struct machine_desc (which is defined in
arch/arm/include/asm/mach/arch.h if you’re curious).

The ‘compatible’ property contains a sorted list of strings starting
with the exact name of the machine, followed by an optional list of
boards it is compatible with sorted from most compatible to least. For
example, the root compatible properties for the TI BeagleBoard and its
successor, the BeagleBoard xM board might look like, respectively:

compatible = “ti,omap3-beagleboard”, “ti,omap3450″, “ti,omap3″;
compatible = “ti,omap3-beagleboard-xm”, “ti,omap3450″, “ti,omap3″;

Where “ti,omap3-beagleboard-xm” specifies the exact model, it also
claims that it compatible with the OMAP 3450 SoC, and the omap3 family
of SoCs in general. You’ll notice that the list is sorted from most
specific (exact board) to least specific (SoC family).

Astute readers might point out that the Beagle xM could also claim
compatibility with the original Beagle board. However, one should be
cautioned about doing so at the board level since there is typically a
high level of change from one board to another, even within the same
product line, and it is hard to nail down exactly what is meant when one
board claims to be compatible with another. For the top level, it is
better to err on the side of caution and not claim one board is
compatible with another. The notable exception would be when one
board is a carrier for another, such as a CPU module attached to a
carrier board.

One more note on compatible values. Any string used in a compatible
property must be documented as to what it indicates. Add
documentation for compatible strings in Documentation/devicetree/bindings.

Again on ARM, for each machine_desc, the kernel looks to see if
any of the dt_compat list entries appear in the compatible property.
If one does, then that machine_desc is a candidate for driving the
machine. After searching the entire table of machine_descs,
setup_machine_fdt() returns the ‘most compatible’ machine_desc based
on which entry in the compatible property each machine_desc matches
against. If no matching machine_desc is found, then it returns NULL.

The reasoning behind this scheme is the observation that in the majority
of cases, a single machine_desc can support a large number of boards
if they all use the same SoC, or same family of SoCs. However,
invariably there will be some exceptions where a specific board will
require special setup code that is not useful in the generic case.
Special cases could be handled by explicitly checking for the
troublesome board(s) in generic setup code, but doing so very quickly
becomes ugly and/or unmaintainable if it is more than just a couple of
cases.

Instead, the compatible list allows a generic machine_desc to provide
support for a wide common set of boards by specifying “less
compatible” values in the dt_compat list. In the example above,
generic board support can claim compatibility with “ti,omap3″ or
“ti,omap3450″. If a bug was discovered on the original beagleboard
that required special workaround code during early boot, then a new
machine_desc could be added which implements the workarounds and only
matches on “ti,omap3-beagleboard”.

PowerPC uses a slightly different scheme where it calls the .probe()
hook from each machine_desc, and the first one returning TRUE is used.
However, this approach does not take into account the priority of the
compatible list, and probably should be avoided for new architecture
support.

2.3 Runtime configuration
————————-
In most cases, a DT will be the sole method of communicating data from
firmware to the kernel, so also gets used to pass in runtime and
configuration data like the kernel parameters string and the location
of an initrd image.

Most of this data is contained in the /chosen node, and when booting
Linux it will look something like this:

chosen {
bootargs = “console=ttyS0,115200 loglevel=8″;
initrd-start = ;
initrd-end = ;
};

The bootargs property contains the kernel arguments, and the initrd-*
properties define the address and size of an initrd blob. Note that
initrd-end is the first address after the initrd image, so this doesn’t
match the usual semantic of struct resource. The chosen node may also
optionally contain an arbitrary number of additional properties for
platform-specific configuration data.

During early boot, the architecture setup code calls of_scan_flat_dt()
several times with different helper callbacks to parse device tree
data before paging is setup. The of_scan_flat_dt() code scans through
the device tree and uses the helpers to extract information required
during early boot. Typically the early_init_dt_scan_chosen() helper
is used to parse the chosen node including kernel parameters,
early_init_dt_scan_root() to initialize the DT address space model,
and early_init_dt_scan_memory() to determine the size and
location of usable RAM.

On ARM, the function setup_machine_fdt() is responsible for early
scanning of the device tree after selecting the correct machine_desc
that supports the board.

2.4 Device population
———————
After the board has been identified, and after the early configuration data
has been parsed, then kernel initialization can proceed in the normal
way. At some point in this process, unflatten_device_tree() is called
to convert the data into a more efficient runtime representation.
This is also when machine-specific setup hooks will get called, like
the machine_desc .init_early(), .init_irq() and .init_machine() hooks
on ARM. The remainder of this section uses examples from the ARM
implementation, but all architectures will do pretty much the same
thing when using a DT.

As can be guessed by the names, .init_early() is used for any machine-
specific setup that needs to be executed early in the boot process,
and .init_irq() is used to set up interrupt handling. Using a DT
doesn’t materially change the behaviour of either of these functions.
If a DT is provided, then both .init_early() and .init_irq() are able
to call any of the DT query functions (of_* in include/linux/of*.h) to
get additional data about the platform.

The most interesting hook in the DT context is .init_machine() which
is primarily responsible for populating the Linux device model with
data about the platform. Historically this has been implemented on
embedded platforms by defining a set of static clock structures,
platform_devices, and other data in the board support .c file, and
registering it en-masse in .init_machine(). When DT is used, then
instead of hard coding static devices for each platform, the list of
devices can be obtained by parsing the DT, and allocating device
structures dynamically.

The simplest case is when .init_machine() is only responsible for
registering a block of platform_devices. A platform_device is a concept
used by Linux for memory or I/O mapped devices which cannot be detected
by hardware, and for ‘composite’ or ‘virtual’ devices (more on those
later). While there is no ‘platform device’ terminology for the DT,
platform devices roughly correspond to device nodes at the root of the
tree and children of simple memory mapped bus nodes.

About now is a good time to lay out an example. Here is part of the
device tree for the NVIDIA Tegra board.

/{
compatible = “nvidia,harmony”, “nvidia,tegra20″;
#address-cells = ;
#size-cells = ;
interrupt-parent = ;

chosen { };
aliases { };

memory {
device_type = “memory”;
reg = ;
};

soc {
compatible = “nvidia,tegra20-soc”, “simple-bus”;
#address-cells = ;
#size-cells = ;
ranges;

intc: interrupt-controller@50041000 {
compatible = “nvidia,tegra20-gic”;
interrupt-controller;
#interrupt-cells = ;
reg = , ;
};

serial@70006300 {
compatible = “nvidia,tegra20-uart”;
reg = ;
interrupts = ;
};

i2s1: i2s@70002800 {
compatible = “nvidia,tegra20-i2s”;
reg = ;
interrupts = ;
codec = ;
};

i2c@7000c000 {
compatible = “nvidia,tegra20-i2c”;
#address-cells = ;
#size-cells = ;
reg = ;
interrupts = ;

wm8903: codec@1a {
compatible = “wlf,wm8903″;
reg = ;
interrupts = ;
};
};
};

sound {
compatible = “nvidia,harmony-sound”;
i2s-controller = ;
i2s-codec = ;
};
};

At .init_machine() time, Tegra board support code will need to look at
this DT and decide which nodes to create platform_devices for.
However, looking at the tree, it is not immediately obvious what kind
of device each node represents, or even if a node represents a device
at all. The /chosen, /aliases, and /memory nodes are informational
nodes that don’t describe devices (although arguably memory could be
considered a device). The children of the /soc node are memory mapped
devices, but the codec@1a is an i2c device, and the sound node
represents not a device, but rather how other devices are connected
together to create the audio subsystem. I know what each device is
because I’m familiar with the board design, but how does the kernel
know what to do with each node?

The trick is that the kernel starts at the root of the tree and looks
for nodes that have a ‘compatible’ property. First, it is generally
assumed that any node with a ‘compatible’ property represents a device
of some kind, and second, it can be assumed that any node at the root
of the tree is either directly attached to the processor bus, or is a
miscellaneous system device that cannot be described any other way.
For each of these nodes, Linux allocates and registers a
platform_device, which in turn may get bound to a platform_driver.

Why is using a platform_device for these nodes a safe assumption?
Well, for the way that Linux models devices, just about all bus_types
assume that its devices are children of a bus controller. For
example, each i2c_client is a child of an i2c_master. Each spi_device
is a child of an SPI bus. Similarly for USB, PCI, MDIO, etc. The
same hierarchy is also found in the DT, where I2C device nodes only
ever appear as children of an I2C bus node. Ditto for SPI, MDIO, USB,
etc. The only devices which do not require a specific type of parent
device are platform_devices (and amba_devices, but more on that
later), which will happily live at the base of the Linux /sys/devices
tree. Therefore, if a DT node is at the root of the tree, then it
really probably is best registered as a platform_device.

Linux board support code calls of_platform_populate(NULL, NULL, NULL, NULL)
to kick off discovery of devices at the root of the tree. The
parameters are all NULL because when starting from the root of the
tree, there is no need to provide a starting node (the first NULL), a
parent struct device (the last NULL), and we’re not using a match
table (yet). For a board that only needs to register devices,
.init_machine() can be completely empty except for the
of_platform_populate() call.

In the Tegra example, this accounts for the /soc and /sound nodes, but
what about the children of the SoC node? Shouldn’t they be registered
as platform devices too? For Linux DT support, the generic behaviour
is for child devices to be registered by the parent’s device driver at
driver .probe() time. So, an i2c bus device driver will register a
i2c_client for each child node, an SPI bus driver will register
its spi_device children, and similarly for other bus_types.
According to that model, a driver could be written that binds to the
SoC node and simply registers platform_devices for each of its
children. The board support code would allocate and register an SoC
device, a (theoretical) SoC device driver could bind to the SoC device,
and register platform_devices for /soc/interrupt-controller, /soc/serial,
/soc/i2s, and /soc/i2c in its .probe() hook. Easy, right?

Actually, it turns out that registering children of some
platform_devices as more platform_devices is a common pattern, and the
device tree support code reflects that and makes the above example
simpler. The second argument to of_platform_populate() is an
of_device_id table, and any node that matches an entry in that table
will also get its child nodes registered. In the Tegra case, the code
can look something like this:

static void __init harmony_init_machine(void)
{
/* … */
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}

“simple-bus” is defined in the ePAPR 1.0 specification as a property
meaning a simple memory mapped bus, so the of_platform_populate() code
could be written to just assume simple-bus compatible nodes will
always be traversed. However, we pass it in as an argument so that
board support code can always override the default behaviour.

[Need to add discussion of adding i2c/spi/etc child devices]

Appendix A: AMBA devices
————————

ARM Primecells are a certain kind of device attached to the ARM AMBA
bus which include some support for hardware detection and power
management. In Linux, struct amba_device and the amba_bus_type is
used to represent Primecell devices. However, the fiddly bit is that
not all devices on an AMBA bus are Primecells, and for Linux it is
typical for both amba_device and platform_device instances to be
siblings of the same bus segment.

When using the DT, this creates problems for of_platform_populate()
because it must decide whether to register each node as either a
platform_device or an amba_device. This unfortunately complicates the
device creation model a little bit, but the solution turns out not to
be too invasive. If a node is compatible with “arm,amba-primecell”, then
of_platform_populate() will register it as an amba_device instead of a
platform_device.

Posted in Uncategorized | Leave a comment

RICS and CICS

The simplest way to examine the advantages and disadvantages of RISC architecture is by contrasting it with it’s predecessor: CISC (Complex Instruction Set Computers) architecture

Multiplying Two Numbers in Memory
On the right is a diagram representing the storage scheme for a generic computer. The main memory is divided into locations numbered from (row) 1: (column) 1 to (row) 6: (column) 4. The execution unit is responsible for carrying out all computations. However, the execution unit can only operate on data that has been loaded into one of the six registers (A, B, C, D, E, or F). Let’s say we want to find the product of two numbers – one stored in location 2:3 and another stored in location 5:2 – and then store the product back in the location 2:3.

The CISC Approach
The primary goal of CISC architecture is to complete a task in as few lines of assembly as possible. This is achieved by building processor hardware that is capable of understanding and executing a series of operations. For this particular task, a CISC processor would come prepared with a specific instruction (we’ll call it “MULT”). When executed, this instruction loads the two values into separate registers, multiplies the operands in the execution unit, and then stores the product in the appropriate register. Thus, the entire task of multiplying two numbers can be completed with one instruction:

MULT 2:3, 5:2
MULT is what is known as a “complex instruction.” It operates directly on the computer’s memory banks and does not require the programmer to explicitly call any loading or storing functions. It closely resembles a command in a higher level language. For instance, if we let “a” represent the value of 2:3 and “b” represent the value of 5:2, then this command is identical to the C statement “a = a * b.”

One of the primary advantages of this system is that the compiler has to do very little work to translate a high-level language statement into assembly. Because the length of the code is relatively short, very little RAM is required to store instructions. The emphasis is put on building complex instructions directly into the hardware.

The RISC Approach
RISC processors only use simple instructions that can be executed within one clock cycle. Thus, the “MULT” command described above could be divided into three separate commands: “LOAD,” which moves data from the memory bank to a register, “PROD,” which finds the product of two operands located within the registers, and “STORE,” which moves data from a register to the memory banks. In order to perform the exact series of steps described in the CISC approach, a programmer would need to code four lines of assembly:

LOAD A, 2:3
LOAD B, 5:2
PROD A, B
STORE 2:3, A
At first, this may seem like a much less efficient way of completing the operation. Because there are more lines of code, more RAM is needed to store the assembly level instructions. The compiler must also perform more work to convert a high-level language statement into code of this form.

CISC RISC
Emphasis on hardware Emphasis on software
Includes multi-clock
complex instructions Single-clock,
reduced instruction only
Memory-to-memory:
“LOAD” and “STORE”
incorporated in instructions Register to register:
“LOAD” and “STORE”
are independent instructions
Small code sizes,
high cycles per second Low cycles per second,
large code sizes
Transistors used for storing
complex instructions Spends more transistors
on memory registers

However, the RISC strategy also brings some very important advantages. Because each instruction requires only one clock cycle to execute, the entire program will execute in approximately the same amount of time as the multi-cycle “MULT” command. These RISC “reduced instructions” require less transistors of hardware space than the complex instructions, leaving more room for general purpose registers. Because all of the instructions execute in a uniform amount of time (i.e. one clock), pipelining is possible.

Separating the “LOAD” and “STORE” instructions actually reduces the amount of work that the computer must perform. After a CISC-style “MULT” command is executed, the processor automatically erases the registers. If one of the operands needs to be used for another computation, the processor must re-load the data from the memory bank into a register. In RISC, the operand will remain in the register until another value is loaded in its place.

The Performance Equation
The following equation is commonly used for expressing a computer’s performance ability:

The CISC approach attempts to minimize the number of instructions per program, sacrificing the number of cycles per instruction. RISC does the opposite, reducing the cycles per instruction at the cost of the number of instructions per program.
RISC Roadblocks
Despite the advantages of RISC based processing, RISC chips took over a decade to gain a foothold in the commercial world. This was largely due to a lack of software support.

Although Apple’s Power Macintosh line featured RISC-based chips and Windows NT was RISC compatible, Windows 3.1 and Windows 95 were designed with CISC processors in mind. Many companies were unwilling to take a chance with the emerging RISC technology. Without commercial interest, processor developers were unable to manufacture RISC chips in large enough volumes to make their price competitive.

Another major setback was the presence of Intel. Although their CISC chips were becoming increasingly unwieldy and difficult to develop, Intel had the resources to plow through development and produce powerful processors. Although RISC chips might surpass Intel’s efforts in specific areas, the differences were not great enough to persuade buyers to change technologies.

The Overall RISC Advantage
Today, the Intel x86 is arguable the only chip which retains CISC architecture. This is primarily due to advancements in other areas of computer technology. The price of RAM has decreased dramatically. In 1977, 1MB of DRAM cost about $5,000. By 1994, the same amount of memory cost only $6 (when adjusted for inflation). Compiler technology has also become more sophisticated, so that the RISC use of RAM and emphasis on software has become ideal.

Posted in Uncategorized | Leave a comment

spi device driver

In the user space

Once you will have this set you can boot your sunxi device and you will have in your dev in /dev/spidevn.0
Transfer size is limited to 64 bytes on sun4i and 128 bytes on sun6i. You have to loop over longer messages in your code. Some SPI devices may require that you prefix each message fragment with a header, other may not. YMMV. Look up transfer diagrams in device datasheet.
Known problems: Using the spidev_test.c example you will receive [spi]: drivers/spi/spi_sunxi.c(L1025) cpu tx data time out!
Using the spidev_fdx.c method it works like a charm! :)

I’ve made a user friendlier library (C functions) to comunicate using SPIdev:
(Note, this library supose the read and write address to be 2 bytes)

#include
#include
#include
#include
#include
#include
#include
#include
#include

char buf[10];
char buf2[10];
extern int com_serial;
extern int failcount;

struct spi_ioc_transfer xfer[2];

//////////
// Init SPIdev
//////////
int spi_init(char filename[40])
{
int file;
__u8 mode, lsb, bits;
__u32 speed=2500000;

if ((file = open(filename,O_RDWR)) < 0)
{
printf("Failed to open the bus.");
/* ERROR HANDLING; you can check errno to see what went wrong */
com_serial=0;
exit(1);
}

///////////////
// Verifications
///////////////
//possible modes: mode |= SPI_LOOP; mode |= SPI_CPHA; mode |= SPI_CPOL; mode |= SPI_LSB_FIRST; mode |= SPI_CS_HIGH; mode |= SPI_3WIRE; mode |= SPI_NO_CS; mode |= SPI_READY;
//multiple possibilities using |
/*
if (ioctl(file, SPI_IOC_WR_MODE, &mode)<0) {
perror("can't set spi mode");
return;
}
*/

if (ioctl(file, SPI_IOC_RD_MODE, &mode) < 0)
{
perror("SPI rd_mode");
return;
}
if (ioctl(file, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
{
perror("SPI rd_lsb_fist");
return;
}
//sunxi supports only 8 bits
/*
if (ioctl(file, SPI_IOC_WR_BITS_PER_WORD, 8)<0)
{
perror("can't set bits per word");
return;
}
*/
if (ioctl(file, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
{
perror("SPI bits_per_word");
return;
}
/*
if (ioctl(file, SPI_IOC_WR_MAX_SPEED_HZ, &speed)<0)
{
perror("can't set max speed hz");
return;
}
*/
if (ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
{
perror("SPI max_speed_hz");
return;
}

printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",filename, mode, bits, lsb ? "(lsb first) " : "", speed);

//xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = 3; /* Length of command to write*/
xfer[0].cs_change = 0; /* Keep CS activated */
xfer[0].delay_usecs = 0, //delay in us
xfer[0].speed_hz = 2500000, //speed
xfer[0].bits_per_word = 8, // bites per word 8

//xfer[1].rx_buf = (unsigned long) buf2;
xfer[1].len = 4; /* Length of Data to read */
xfer[1].cs_change = 0; /* Keep CS activated */
xfer[0].delay_usecs = 0;
xfer[0].speed_hz = 2500000;
xfer[0].bits_per_word = 8;

return file;
}

//////////
// Read n bytes from the 2 bytes add1 add2 address
//////////

char * spi_read(int add1,int add2,int nbytes,int file)
{
int status;

memset(buf, 0, sizeof buf);
memset(buf2, 0, sizeof buf2);
buf[0] = 0×01;
buf[1] = add1;
buf[2] = add2;
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = 3; /* Length of command to write*/
xfer[1].rx_buf = (unsigned long) buf2;
xfer[1].len = nbytes; /* Length of Data to read */
status = ioctl(file, SPI_IOC_MESSAGE(2), xfer);
if (status =1) buf[3] = value[0];
if (nbytes>=2) buf[4] = value[1];
if (nbytes>=3) buf[5] = value[2];
if (nbytes>=4) buf[6] = value[3];
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = nbytes+3; /* Length of command to write*/
status = ioctl(file, SPI_IOC_MESSAGE(1), xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
return;
}
//printf("env: %02x %02x %02x\n", buf[0], buf[1], buf[2]);
//printf("ret: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);

com_serial=1;
failcount=0;
}

Usage example:
char *buffer;
char buf[10];

file=spi_init("/dev/spidev0.0"); //dev

buf[0] = 0×41;
buf[1] = 0xFF;
spi_write(0xE6,0x0E,2,buf,file); //this will write value 0x41FF to the address 0xE60E

buffer=(char *)spi_read(0xE6,0x0E,4,file); //reading the address 0xE60E

close(file);

For info it is possible to use all the 12000000 Hz frequency limit transfers.
In the kernel space

If you are coding a driver for a SPI device, it makes most sense to code it as a kernel module. Instead of using /dev/spidevX.X you should register a new (slave) device and exchange data through it. If you are wondering what bus number you should use, you can find available buses by listing /sys/class/spi_master. There should be nodes like spi0, spi1… Number after spi is bus number. What number gets spi master depends on device-tree configuration.

Here is an example of module, that writes 0×00 to SPI when module is initialized and 0xff when uninitialized. It is using bus number 0 and communicating at the speed of 1Hz:

#include
#include
#include

#define MY_BUS_NUM 0
static struct spi_device *spi_device;

static int __init spi_init(void)
{
int ret;
unsigned char ch = 0×00;
struct spi_master *master;

//Register information about your slave device:
struct spi_board_info spi_device_info = {
.modalias = “my-device-driver-name”,
.max_speed_hz = 1, //speed your device (slave) can handle
.bus_num = MY_BUS_NUM,
.chip_select = 0,
.mode = 3,
};

/*To send data we have to know what spi port/pins should be used. This information
can be found in the device-tree. */
master = spi_busnum_to_master( spi_device_info.bus_num );
if( !master ){
printk(“MASTER not found.\n”);
return -ENODEV;
}

// create a new slave device, given the master and device info
spi_device = spi_new_device( master, &spi_device_info );

if( !spi_device ) {
printk(“FAILED to create slave.\n”);
return -ENODEV;
}

spi_device->bits_per_word = 8;

ret = spi_setup( spi_device );

if( ret ){
printk(“FAILED to setup slave.\n”);
spi_unregister_device( spi_device );
return -ENODEV;
}

spi_write(spi_device, &ch, sizeof(ch));

return 0;
}

static void __exit spi_exit(void)
{
unsigned char ch = 0Xff;

if( spi_device ){
spi_write(spi_device, &ch, sizeof(ch));
spi_unregister_device( spi_device );
}
}

module_init(spi_init);
module_exit(spi_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“Piktas Zuikis “);
MODULE_DESCRIPTION(“SPI module example”);

Posted in Uncategorized | Leave a comment

.Fex Guide

Fex Guide
Contents [hide]
1 FEX Description
2 Port Definitions
3 application
3.1 [product]
4 system configuration
4.1 [target]
4.2 [card_burn_para]
4.3 [card_boot]
4.4 [card_boot0_para]
4.5 [card_boot2_para]
4.6 [twi_para]
4.7 [uart_para]
4.8 [jtag_para]
4.9 [system]
4.10 [gpio_para]
4.11 [gpio_init]
5 SDRAM
5.1 [dram_para]
6 mali configuration
6.1 [mali_para]
6.2 [g2d_para]
7 ethernet MAC configuration
7.1 [emac_para]
8 i2c configuration
8.1 [twi0_para]
8.2 [twi0_para]
8.3 [twi2_para]
9 uart configuration
9.1 [uart_para0]
9.2 [uart_para1]
9.3 [uart_para2]
9.4 [uart_para3]
9.5 [uart_para4]
9.6 [uart_para5]
9.7 [uart_para6]
9.8 [uart_para7]
10 spi configuration
10.1 [spi0_para]
10.2 [spi1_para]
10.3 [spi2_para]
10.4 [spi3_para]
11 external spi device configuration
11.1 [spi_devices]
11.2 [spi_board0]
12 resistive touch panel configuration
12.1 [rtp_para]
13 capacitive touch panel configuration
13.1 [ctp_para]
14 touch key configuration
14.1 [tkey_para]
15 tablet key configuration
15.1 [tabletkeys_para]
16 motor configuration
16.1 [motor_para]
17 lock configuration
17.1 [locks_para]
18 nand flash configuration
18.1 [nand_para]
19 boot disp configuration
19.1 [boot_disp]
20 disp init configuration
20.1 [disp_init]
21 lcd[0/1] configuration
21.1 [lcd0_para]
21.2 [lcd1_para]
22 tv out dac configuration
22.1 [tv_out_dac_para]
23 csi gpio configuration
23.1 [csi0_para]
23.2 [csi1_para]
24 tv configuration
24.1 [tvout_para]
24.2 [tvin_para]
25 sata configuration
25.1 [sata_para]
26 sdmmc configuration
26.1 [mmc0_para]
26.2 [mmc1_para]
26.3 [mmc2_para]
26.4 [mmc3_para]
27 memory stick configuration
27.1 [ms_para]
28 sim card configuration
28.1 [smc_para]
29 ps2 configuration
29.1 [ps2_0_para]
29.2 [ps2_1_para]
30 can bus configuration
30.1 [can_para]
31 matrix keyboard
32 23.1 [keypad_para]
33 USB control flags
33.1 [usbc0]
33.2 [usbc1]
33.3 [usbc2]
34 USB Device
34.1 [usb_feature]
34.2 [msc_feature]
35 G Sensor configuration
35.1 [gsensor_para]
36 gps gpio configuration
36.1 [gps_para]
37 sdio wifi configuration
37.1 [sdio_wifi_para]
38 us wifi configuration
38.1 [usb_wifi_para]
39 3G configuration
39.1 [3g_para]
40 gyroscope
40.1 [gy_para]
41 light sensor
41.1 [ls_para]
42 compass
42.1 [compass_para]
43 blue tooth
43.1 [bt_para]
44 i2s configuration
44.1 [i2s_para]
45 spdif configuration
45.1 [spdif_para]
46 audio configuration
46.1 [audio_para]
47 infrared remote configuration
47.1 [ir_para]
48 pmu configuration
48.1 [pmu_para]
49 recovery key configuration
49.1 [recovery_key]
50 dvfs voltage-frequency table configuration
50.1 [dvfs_table]
51 led configuration
51.1 [leds_para]
51.2 external leds
52 dynamic configuration
52.1 [dynamic]
FEX Description

A FEX file defines various aspects of how the SoC works. It configures the GPIO pins and sets up DRAM, Display, etc parameters. It is Allwinners predecessor for the devicetree.

Each line consists of a key = value pair combination under a [sectionheader]. All three, [sectionheader], key and value are case-sensitive. For comments a semi-colon (;) is used and everything following a semi-colon is ignored. The chip does not parse a textual version of a fex file, it gets cleaned and compiled by a fex-compiler. A reverse engineerd open source version exists in the sunxi-tools repository. Also a de-compiler which takes a binary script.bin and creates a textual script.fex. Usually, script.bin can be found on the nanda boot partition on A10 devices.
Sticky-note-pin.png Note: The mainline Linux kernel makes no use of FEX / script.bin, and relies on the device tree model instead (.dtb files).

Port Definitions

Description of the GPIO configuration in the form:
port:
where:
is the port to configure (ie. PH15)
is the function to configure the port for, mux 0 is as input, mux 1 as output and for 2-7 see A10/PIO, A13/PIO, or A20/PIO for details.
is 0 = disabled; 1 = pullup enabled; 2 = pulldown enabled (only valid when port is an input)
defines the output drive in mA, values are 0-3 corresponding to 10mA, 20mA, 30mA and 40mA.
sets the initial output level for the port; 0 = low; 1 = high (only valid for outputs)
The and can be set to which means don’t change. Any trailing options can be omitted.
This can also be used to specify various pins on the AXP PMIC. The syntax is “power:portN”.
Port AXP20x AXP22x / AXP8xx
0 GPIO0 GPIO0
1 GPIO1 GPIO1
2 GPIO2 DC1SW
3 GPIO3 CHGLED
4 N_VBUSEN
5 WAKEUP (slave PMIC)
6 SWOUT (slave PMIC)
application

[product]
Product version and description. It seems all fex files at this moment are at version 1.0 and use the default evaluation board name. It doesn’t appear to be used internally, but requires further investigation.
version: string indicating fex file version.
machine: string indicating the board name. “A10-EVB-V1.2″ appears to be a common one, seemingly to refer to the A10
[product]
version = “1.0″
machine = “A10-EVB-V1.2″
system configuration

[target]
Sticky-note-pin.png Note: blue module chip pin configuration, the black module internal control configuration
Configuration items to configure the meaning of
boot_clock: Initial boot frequency in MHz.
dcdc2_vol: Dcdc2 output voltage in mV.
dcdc3_vol: Dcdc3 output voltage in mV.
ldo2_vol: Ldo2 output voltage in mV.
ldo3_vol: Ldo3 output voltage in mV.
ldo4_vol: Ldo4 output voltage in mV.
power_start: 0 or 1.
storage_type: 0 = nand, 1 = SDCard, 2 = SPI-nor

[target]
boot_clock = 1008
dcdc2_vol = 1400
dcdc3_vol = 1250
ldo2_vol = 3000
ldo3_vol = 2800
ldo4_vol = 2800
pll4_freq = 960
pll6_freq = 960
power_start = 1
storage_type = 0
[card_burn_para]
Configuration example:

[card_burn_para]
card_no = 0
card_line = 4
card_mode = 0
sdc_d1 = port:PF00
sdc_d0 = port:PF01
sdc_clk = port:PF02
sdc_cmd = port:PF03
sdc_d3 = port:PF04
sdc_d2 = port:PF05
[card_boot]
logical_start: logical starting address when booting from SD-Card.
sprite_gpio0:
Configuration example:

[Card_boot]
logical_start = 40960
sprite_gpio0 =
[card_boot0_para]
card_ctrl: card controller to be used
card_high_speed: 0 for low speed, 1 for high-speed
card_line: Number of card data lines
sdc_ cmd: SD-Card command signals GPIO configuration
sdc_ clk: SD-Card clock signal GPIO configuration
sdc_ d0: SD-Card data 0 line signal GPIO configuration
sdc_ d1: SD-Card data 1 line signal GPIO configuration
sdc_d2: SD-Card data 2 line signal GPIO configuration
sdc_d3: SD-Card data 3 line signal GPIO configuration

[card_boot0_para]
card_ctrl = 0
card_high_speed = 1
card_line = 4
sdc_d1 = port:PF00
sdc_d0 = port:PF01
sdc_clk = port:PF02
sdc_cmd = port:PF03
sdc_d3 = port:PF04
sdc_d2 = port:PF05
[card_boot2_para]
card_ctrl: card controller to be used
card_high_speed: 0 for low speed, 1 for high-speed
card_line: number of card data lines
sdc_ cmd: SD-Card command signals GPIO configuration
sdc_ clk: SD-Card clock signal GPIO configuration
sdc_ d0: SD-Card data 0 line signal GPIO configuration
sdc_ d1: SD-Card data 1 line signal GPIO configuration
sdc_d2: SD-Card data 2 line signal GPIO configuration
sdc_d3: SD-Card data 3 line signal GPIO configuration

[card_boot2_para]
card_ctrl = 2
card_high_speed = 1
card_line = 4
sdc_cmd = port:PC06
sdc_clk = port:PC07
sdc_d0 = port:PC08
sdc_d1 = port:PC09
sdc_d2 = port:PC10
sdc_d3 = port:PC11
[twi_para]
twi controller to enable during/for boot.
twi_port: twi controller to configure
twi_scl: twi Serial CLock line GPIO configuration
twi_sda: = twi Serial DAta line GPIO configuration

[twi_para]
twi_port = 0
twi_scl = port:PB00
twi_sda = port:PB01
[uart_para]
Serial port to be enabled during/for boot.
uart_debug_port: serial controller number
uart_debug_tx: serial port TX line GPIO configuration
uart_debug_rx: serial port RX line GPIO configuration

[uart_para]
uart_debug_port = 0
uart_debug_tx = port:PB22
uart_debug_rx = port:PB23
[jtag_para]
JTAG port to be enabled during/for boot.
jtag_enable: 0 to disable JTAG, 1 to enable JTAG
jtag_ms: JTAG Test Mode Select (TMS) GPIO configuration
jtag_ck: JTAG Test Clock (TCK) GPIO configuration
jtag_do: JTAG Test Data Output (TDO) GPIO configuration
jtag_di: JTAG Test Data Input (TDI) GPIO configuration

[jtag_para]
jtag_enable = 1
jtag_ms = port:PB14
jtag_ck = port:PB15default>
jtag_do = port:PB16default>
jtag_di = port:PB17default>
[system]
recovery_key: recovery key GPIO configuration
Configuration example:
recovery_key = port:PH16
[gpio_para]
gpio_used: 0 to disable; 1 to enable
gpio_num: number mapped GPIO’s
gpio_pin_1: first GPIO pin
Configuration example:
gpio_used = 0
gpio_num = 4
gpio_pin_1 = port:PH10
gpio_pin_2 = port:PH20
gpio_pin_3 = port:PB03
gpio_pin_4 = port:PH22
[gpio_init]
pin_1: Initial pin 1 GPIO configuration
Configuration example:
pin_1 = port:PH10
pin_2 = port:PH20
SDRAM

[dram_para]
SD-Ram is usually configured via livesuit when flashing. Livesuit probes the hardware or knows about the hardware and its configuration and configures the SoC accordingly. This luxury is not available from Linux and thus sdram parameters have to be set up by hand.
dram_baseaddr: DRAM physical start address, fixed at 0×40000000
dram_clk: DRAM clock frequency in MHz; it must be an integer multiple of 24, minimally 120, maximally 480 MHz
dram_type: DRAM type; Set to 2 for DDR2; 3 for DDR3
dram_rank_num: DRAM chip select; 1 is a chip select; 2 election for two tablets
dram_chip_density: monolithic DRAM capacity in Mbit
dram_io_width: monolithic DRAM bus width in bits
dram_bus_width: DRAM bus width in bits, such as two 16-bit DRAM banks make up a 32 bit bus width
dram_cas: DRAM CAS latency
dram_zq: DRAM controller internal parameters
dram_odt_en: ODT 0 to disable; 1 to enable
dram_size: DRAM total capacity in MB
dram_tpr0: DRAM controller internal parameter
dram_tpr1: DRAM controller internal parameter
dram_tpr2: DRAM controller internal parameter
dram_tpr3: DRAM controller internal parameter
dram_tpr4: DRAM controller internal parameter
dram_tpr5: DRAM controller internal parameter
dram_emr1: DRAM controller internal parameter
dram_emr2: DRAM controller internal parameter
dram_emr3: DRAM controller internal parameter
Configuration example:

[dram_para]
dram_baseaddr = 0×40000000
dram_clk = 360
dram_type = 3
dram_rank_num = 1
dram_chip_density = 2048
dram_io_width = 16
dram_bus_width = 32
dram_cas = 6
dram_zq = 0x7b
dram_odt_en = 0
dram_size = 512
dram_tpr0 = 0×30926692
dram_tpr1 = 0×1090
dram_tpr2 = 0x1a0c8
dram_tpr3 = 0×0
dram_tpr4 = 0×0
dram_tpr5 = 0×0
dram_emr1 = 0×0
dram_emr2 = 0×0
dram_emr3 = 0×0
mali configuration

Mali is the name of the GPU on the A10, A10s, A13, A20, A23, and A33 SoC’s
[mali_para]
mali_used: 0 to disable; 1 to enable Mali module
mali_clkdiv: Mali clock divisor. Clock is obtained by devising PLL4 with mali_clkdiv
Configuration example:

[mali_para]
mali_used = 1
mali_clkdiv = 3
[g2d_para]
G2D is the 2D graphic display engine on the Allwinner SoC
g2d_used: 0 to disable; 1 to enable the g2d module
g2d_size: memory size for g2d

g2d_used = 1
g2d_size = 0×1000000
ethernet MAC configuration

[emac_para]
Ethernet configuration for the integrated ethernet IP. It still requires an external PHY
emac_used: 0 to disable; 1 to enable the ethernet MAC
emac_rxd0: RX data line 0 GPIO configuration
emac_rxd1: RX data line 1 GPIO configuration
emac_rxd2: RX data line 2 GPIO configuration
emac_rxd3: RX data line 3 GPIO configuration
emac_txd0: TX data line 0 GPIO configuration
emac_txd1: TX data line 1 GPIO configuration
emac_txd2: TX data line 2 GPIO configuration
emac_txd3: TX data line 3 GPIO configuration
emac_rxclk: RX clock GPIO configuration
emac_rxerr: RX error GPIO configuration
emac_rxdV: RX enabled GPIO configuration
emac_mdc: MII clock GPIO configuration
emac_mdio: MII data I/O GPIO configuration
emac_txen: TX enabled GPIO configuration
emac_txclk: TX clock GPIO configuration
emac_crs: Carrier Status of GPIO configuration
emac_col: Collision Detection GPIO configuration
emac_reset: PHY reset signal GPIO configuration
emac_power:
emac_link:
Configuration example:

[Emac_para]
emac_used = 1
emac_rxd3 = port:PA00
emac_rxd2 = port:PA01
emac_rxd1 = port:PA02
emac_rxd0 = port:PA03
emac_txd3 = port:PA04
emac_txd2 = port:PA05
emac_txd1 = port:PA06
emac_txd0 = port:PA07
emac_rxclk = port:PA08
emac_rxerr = port:PA09
emac_rxdV = port:PA10
emac_mdc = port:PA11
emac_mdio = port:PA12
emac_txen = port:PA13
emac_txclk = port:PA14
emac_crs = port:PA15
emac_col = port:PA16
emac_reset = port:PA17
i2c configuration

[twi0_para]
Two Wire Interface (i²c) configuration for TWI port 0
twi0_used: 0 to disable; 1 to enable
twi0_scl: TWI Serial CLock GPIO configuration
twi0_sda: TWI Serial Data GPIO configuration
Configuration example:
?
1
2
3
4
[twi0_para]
twi0_used = 1
twi0_scl = port:PB00
twi0_sda = port:PB01
[twi0_para]
Two Wire Interface (i²c) configuration for TWI port 1
twi1_used: 0 to disable; 1 to enable
twi1_scl: TWI Serial CLock GPIO configuration
twi1_sda: TWI Serial Data GPIO configuration
Configuration example:
?
1
2
3
4
[tw1_para]
twi1_used = 1
twi1_scl = port:PB18
twi1_sda = port:PB19
[twi2_para]
Two Wire Interface (i²c) configuration for TWI port 2
twi2_used: 0 to disable; 1 to enable
twi2_scl: TWI Serial CLock GPIO configuration
twi2_sda: TWI Serial Data GPIO configuration
Configuration example:
?
1
2
3
4
[twi2_para]
twi2_used = 1
twi2_scl = port:PB20
twi2_sda = port:PB21
uart configuration

Any of the 8 UART ports can be configured to be either 2 (Only TX/RX) wires, 4 wires (TX, RX, RTS and CTS) or 8 (Full function) ports.
uart_used: 0 to disable; 1 to enable
uart_port: UART port number
uart_type: UART type, 2, 4 or 8 wires
uart_tx: UART TX data line GPIO configuration
uart_rx: UART RX data line GPIO configuration
uart_rts: UART Ready to Send line GPIO configuration, only for 4 and 8 wire modes
uart_cts: UART Clear to Send line GPIO configuration, only for 4 and 8 wire modes
uart_dtr: UART Data Terminal Ready GPIO configuration, only for 8 wire modes
uart_dsr: UART Data Set Ready GPIO configuration, only for 8 wire modes
uart_dcd: UART Data Carrier Detect GPIO configuration, only for 8 wire modes
uart_ring: UART Ring Indicator GPIO configuration, only for 8 wire modes
[uart_para0]
Configuration example:
?
1
2
3
4
5
[uart_para0]
uart_used = 1
uart_port = 0
uart_tx = port:PB22
uart_rx = port:PB23
[uart_para1]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
[uart_para1]
uart_used = 0
uart_port = 1
uart_type = 8
uart_tx = port:PA10
uart_rx = port:PA11
uart_rts = port:PA12
uart_cts = port:PA13
uart_dtr = port:PA14
uart_dsr = port:PA15
uart_dcd = port:PA16
uart_ring = port:PA17
[uart_para2]
Configuration example:
?
1
2
3
4
5
6
7
8
[uart_para2]
uart_used = 0
uart_port = 2
uart_type = 4
uart_tx = port:PI18
uart_rx = port:PI19
uart_rts = port:PI16
uart_cts = port:PI17
[uart_para3]
Configuration example:
?
1
2
3
4
5
6
7
8
[uart_para3]
uart_used = 0
uart_port = 3
uart_type = 4
uart_tx = port:PH00
uart_rx = port:PH01
uart_rts = port:PH02
uart_cts = port:PH03
[uart_para4]
Configuration example:
?
1
2
3
4
5
6
[Uart_para4]
uart_used = 0
uart_port = 4
uart_type = 2
uart_tx = port:PH04
uart_rx = port:PH05
[uart_para5]
Configuration example:
?
1
2
3
4
5
6
[uart_para5]
uart_used = 0
uart_port = 5
uart_type = 2
uart_tx = port: PH06
uart_rx = port: PH07
[uart_para6]
Configuration example:
?
1
2
3
4
5
6
[uart_para6]
uart_used = 0
uart_port = 6
uart_type = 2
uart_tx = port:PA12
uart_rx = port:PA13
[uart_para7]
Configuration example:
?
1
2
3
4
5
6
[uart_para7]
uart_used = 0
uart_port = 7
uart_type = 2
uart_tx = port:PA14
uart_rx = port:PA15
spi configuration

spi_used: 0 to disable; 1 to enable
spi_cs_bitmap: 1 use cs0, 2 use cs1, 3 use cs0 & cs1
spi_cs0: Chip Select bit 0 GPIO configuration
spi_cs1: Chip Select bit 1 GPIO configuration
spi_sclk: clock GPIO configuration
spi_mosi: MOSI GPIO configuration
spi_miso: MISO GPIO configuration
Sticky-note-pin.png Note: Not all spi chip select bits are required to be set
[spi0_para]
Configuration example 1:
?
1
2
3
4
5
6
7
8
[spi0_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PI10
spi_sclk = port:PI11
spi_mosi = port:PI12
spi_miso = port:PI13
spi_cs1 = port:PI14
Configuration example 2:
?
1
2
3
4
5
6
7
[spi0_para]
spi_used = 0
spi_cs_bitmap = 1
spi_mosi = port:PC00
spi_miso = port:PC01
spi_sclk = port:PC02
spi_cs0 = port:PC23
[spi1_para]
Configuration example 1:
?
1
2
3
4
5
6
7
8
[spi1_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PA00
spi_sclk = port:PA01
spi_mosi = port:PA02
spi_miso = port:PA03
spi_cs1 = port:PA04
Configuration example 2:
?
1
2
3
4
5
6
7
8
[spi1_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs1 = port:PI15
spi_cs0 = port:PI16
spi_sclk = port:PI17
spi_mosi = port:PI18
spi_miso = port:PI19
[spi2_para]
Configuration example 1:
?
1
2
3
4
5
6
7
8
[spi2_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs1 = port:PB13
spi_cs0 = port:PB14
spi_sclk = port:PB15
spi_mosi = port:PB16
spi_miso = port:PB17
Configuration example 2:
?
1
2
3
4
5
6
7
[spi2_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PC19
spi_sclk = port:PC20
spi_mosi = port:PC21
spi_miso = port:PC23
[spi3_para]
Configuration example:
?
1
2
3
4
5
6
7
8
[spi3_para]
spi_used = 0
spi_cs_bitmap = 1
spi_cs0 = port:PA05
spi_sclk = port:PA06
spi_mosi = port:PA07
spi_miso = port:PA08
spi_cs1 = port:PA09
external spi device configuration

[spi_devices]
spi_dev_num: number of external SPI devices connected to the SoC. For each external SPI device N, a board define [spi_boardM] with M = N – 1 needs to be created
[spi_board0]
modalias: Alias
max_speed_hz: Maximum speed in Hz
bus_num: Bus number of SPI controller
mode: SPI mode, bitfield defined in spi.h
full_duplex: 0 for half-duplex; 1 for full-duplex mode
manual_cs: manually control Chip Select level (unsupported for now)
irq_gpio: Some SPI boards should need a IRQ to work properly and register the irq handler inside the device driver
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[spi_board0]
modalias = “External SPI connection”
max_speed_hz = 12000000
bus_num = 1
chip_select = 0
mode = 3
full_duplex = 0
manual_cs = 0
irq_gpio = 1

[gpio_para]
gpio_used = 1
gpio_num = 1
gpio_pin_1 = port:PB04
resistive touch panel configuration

[rtp_para]
rtp_used: 0 to disable; 1 to enable
rtp_screen_size: diagonal screen size rounded to full inches
rtp_regidity_level: touchscreen regidty in 10 ms units
rtp_press_threshold_enable: 0 to disable; 1 to enable
rtp_press_threshold: defines the press-threshold sensitivity; (0×0 is least sensitive, 0xffffff is most sensitive) using TP Pressure Management threshold control (PRE_MEA_THRE_CNT register in A20 User Manual)
rtp_sensitive_level: defines the sensitivity (0×0 is least sensitive, 0xf is most sensitive) using internal pull-up resistor control (TP_SENSITIVE_ADJUST register in A20 User Manual)
rtp_exchange_x_y_flag: 0 for normal operation; 1 to flip X and Y coordinates
Configuration example:
?
1
2
3
4
5
6
7
rtp_used = 0
rtp_screen_size = 7
rtp_regidity_level = 7
rtp_press_threshold_enable = 0
rtp_press_threshold = 0x1f40
rtp_sensitive_level = 0xf
rtp_exchange_x_y_flag = 0
capacitive touch panel configuration

[ctp_para]
Several touch panel’s can be configured. Their name must match to the linux ctp-driver!
ctp_used: 0 to disable; 1 to enable
ctp_name: Name of the touch panel driver to use
ctp_twi_id: twi controller to use
ctp_twi_addr: hardware specfic twi address in hex
ctp_screen_rotate: 0 for normal operation; 1 for 180° rotation
ctp_screen_max_x: Maximum X screen resolution
ctp_screen_max_y: Maximum Y screen resolution
ctp_revert_x_flag: 0 for normal operation; 1 to flip the X axis
ctp_revert_y_flag: 0 for normal operation; 1 to flip the Y axis
ctp_havekey: 0 for normal operation; 1 if the touch panel also has touch-keys.
ctp_int_port: interrupt line GPIO configuration
ctp_wakeup: screen wake up GPIO configuration
ctp_io_port: I/O port GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[ctp_para]
ctp_used = 1
ctp_twi_id = 2
ctp_name = “ft5x_ts”
ctp_twi_addr = 0×38

ctp1_used = 1
ctp1_name = “Goodix-TS”
ctp1_twi_addr = 0×55

ctp2_used = 1
ctp2_name = “ssd253x-ts”
ctp2_twi_addr = 0×48

ctp3_used = 1
ctp3_name = “novatek-ts”
ctp3_twi_addr = 0×09

ctp4_used = 1
ctp4_name = “zet622x-ts”
ctp4_twi_addr = 0×76

ctp5_used = 1
ctp5_name = “byd693x-ts”
ctp5_twi_addr = 0×52

ctp6_used = 0
ctp6_name = “gt82x”
ctp6_twi_addr = 0x5d

ctp7_used = 0
ctp7_name = “px811″
ctp7_twi_addr = 0x5c

ctp_screen_rotate = 0
ctp_screen_max_x = 800
ctp_screen_max_y = 480
ctp_revert_x_flag = 0
ctp_revert_y_flag = 0
ctp_exchange_x_y_flag = 0
ctp_havekey = 0
ctp_int_port = port: PH21
ctp_wakeup = port: PB13
ctp_io_port = port: PH21
touch key configuration

[tkey_para]
Touch ‘key’, only for “hv_keypad” for now
tkey_used: 0 to disable; 1 to enable
tkey_name: driver name, must match linux driver name
tkey_twi_id: twi controller to use
tkey_twi_addr: hardware specfic twi address in hex
tkey_int: interrupt line GPIO configuration
Configuration example:
?
1
2
3
4
5
6
[tkey_para]
tkey_used = 0
tkey_name = “hv_keypad”
tkey_twi_id = 2
tkey_twi_addr = 0×62
tkey_int = port: PI13
tablet key configuration

Configures tablet physical buttons – usually Vol+ and Vol-, may have Home, Back and others.
Power key is usually handled by the AXP PMU. Buttons like reset and FEL are special and should work without a driver.
[tabletkeys_para]
tabletkeys_used: 0 to disable; 1 to enable
keyN_code: numeric keycode – easily found with evtest. N seems to be 0-4 by default.
Configuration example:
?
1
2
3
4
[tabletkeys_para]
tabletkeys_used=1
key0_code = 114
key1_code = 115
motor configuration

[motor_para]
motor_used: 0 to disable; 1 to enable
motor_shake: motor control pin GPIO configuration
Configuration example:
?
1
2
3
[motor_para]
motor_used = 0
motor_shake = port:PB03
lock configuration

Locks are either very new or really old as nothing can be found in any fex file in git. It seems reasonable to believe that this would be a screen lock ‘button’.
[locks_para]
locks_used: 0 to disable; 1 to enable
locks_gpio: switch GPIO configuration
Configuration example:
?
1
2
3
[locks_para]
locks_used = 0
locks_gpio = port:PH00
nand flash configuration

[nand_para]
nand_used: 0 to disable; 1 to enable
nand_we: Write Enable GPIO configuration
nand_ale: Address Latch Enable GPIO configuration
nand_cle: Command Latch Enable GPIO configuration
nand_ce0: Chip sElect bit 0 GPIO configuration
nand_ce1: Chip sElect bit 1 GPIO configuration
nand_ce2: Chip sElect bit 2 GPIO configuration
nand_ce3: Chip sElect bit 3 GPIO configuration
nand_ce4: Chip sElect bit 4 GPIO configuration
nand_ce5: Chip sElect bit 5 GPIO configuration
nand_ce6: Chip sElect bit 6 GPIO configuration
nand_ce7: Chip sElect bit 7 GPIO configuration
nand_nre: Nand Read Enable GPIO configuration
nand_rb0: Read / Busy bit 0 GPIO configuration
nand_rb1: Read / Busy bit 1 GPIO configuration
nand_d0: data bus bit 0 GPIO configuration
nand_d1: data bus bit 1 GPIO configuration
nand_d2: data bus bit 2 GPIO configuration
nand_d3: data bus bit 3 GPIO configuration
nand_d4: data bus bit 4 GPIO configuration
nand_d5: data bus bit 5 GPIO configuration
nand_d6: data bus bit 6 GPIO configuration
nand_d7: data bus bit 7 GPIO configuration
nand_wp: Write Protect GPIO configuration
nand_spi: SPI data line GPIO configuration
nand_ndqs: nand ddr clock signal GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[Nand_para]
nand_used = 1
nand_we = port:PC00
nand_ale = port:PC01
nand_cle = port:PC02
nand_ce1 = port:PC03
nand_ce0 = port:PC04
nand_nre = port:PC05
nand_rb0 = port:PC06
nand_rb1 = port:PC07
nand_d0 = port:PC08
nand_d1 = port:PC09
nand_d2 = port:PC10
nand_d3 = port:PC11
nand_d4 = port:PC12
nand_d5 = port:PC13
nand_d6 = port:PC14
nand_d7 = port:PC15
nand_wp = port:PC16
nand_ce2 = port:PC17
nand_ce3 = port:PC18
nand_ce4 = port:PC19
nand_ce5 = port:PC20
nand_ce6 = port:PC21
nand_ce7 = port:PC22
nand_spi = port:PC23
nand_ndqs = port:PC24
boot disp configuration

[boot_disp]
This section can be found in vendor fex files for H3 devices and is only used by Allwinner’s BSP u-boot (eg. to display a boot logo which might require further patches)
disp init configuration

[disp_init]
disp_init_enable: 0 to disable; 1 to enable
disp_mode: Display mode to use:
mode display mode
0 screen0(screen0, fb0)
1 screen1(screen1, fb0)
2 dualhead(screen0, screen1, fb0, fb1) (2 screens, 2 framebuffers)
3 xinerama(screen0, screen1, fb0) (2 screens, one big framebuffer)
4 clone(screen0, screen1, fb0) (2 screens, one standard framebuffer)
screen0_out_color_range: Output color range for HDMI (applies to both screen0/screen1 – there is no screen1_out_color_range):
type output color range
0 16-255 Limited Range (Default)
1 0-255 Full Range – PC Level
2 16-235 Limited Range – Video Level
screen0_output_type: Output type for screen0:
screen1_output_type: Output type for screen1:
type Output type
0 NONE
1 LCD
2 TV
3 HDMI
4 VGA
screen0_output_mode: Output mode for screen0:
screen1_output_mode: Output mode for screen1:
mode used for tv/hdmi output used for vga output
0 480i 1680*1050
1 576i 1440*900
2 480p 1360*768
3 576p 1280*1024
4 720p50 1024*768
5 720p60 800*600
6 1080i50 640*480
7 1080i60
8 1080p24
9 1080p50
10 1080p60 1920*1080
11 pal 1280*720
14 ntsc
fb0_framebuffer_num: fb0 buffer number, use 2 for double buffering
fb1_framebuffer_num: fb1 buffer number, use 2 for double buffering
fb0_format: pixel format for fb0:
fb1_format: pixel format for fb1:
format fb0_format
4 RGB655
5 RGB565
6 RGB556
7 ARGB1555
8 RGBA5551
9 RGB888
10 ARGB8888
12 ARGB4444
fb0_pixel_sequence: fb0 pixel sequence (0 generally for linux, 2 for android):
fb1_pixel_sequence: fb1 pixel sequence (0 generally for linux, 2 for android):
sequence fb0_pixel_sequence
0 ARGB
2 BGRA
fb0_scaler_mode_enable: 0 to disable; 1 to enable
fb1_scaler_mode_enable: 0 to disable; 1 to enable
lcd0_backlight: value to 240 sets PWM rate on selected PWM gpio
lcd1_backlight: value to 240 sets PWM rate on selected PWM gpio

Configuration example for LCD:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[disp_init]
disp_init_enable = 1
disp_mode = 0

screen0_output_type = 1
screen0_output_mode = 4

screen1_output_type = 1
screen1_output_mode = 4

fb0_framebuffer_num = 2
fb0_format = 10
fb0_pixel_sequence = 0
fb0_scaler_mode_enable = 0

fb1_framebuffer_num = 2
fb1_format = 10
fb1_pixel_sequence = 0
fb1_scaler_mode_enable = 0
Configuration example for VGA:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[disp_init]
disp_init_enable = 1
disp_mode = 0

screen0_output_type = 4
screen0_output_mode = 4

screen1_output_type = 2
screen1_output_mode = 14

fb0_framebuffer_num = 2
fb0_format = 10
fb0_pixel_sequence = 0
fb0_scaler_mode_enable = 1

fb1_framebuffer_num = 2
fb1_format = 10
fb1_pixel_sequence = 0
fb1_scaler_mode_enable = 1
Configuration example for Composite TV on an old TV (PAL mode):
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[disp_init]
disp_init_enable = 1
disp_mode = 0

screen0_output_type = 2
screen0_output_mode = 11

screen1_output_type = 2
screen1_output_mode = 11

fb0_framebuffer_num = 2
fb0_format = 10
fb0_pixel_sequence = 0
fb0_scaler_mode_enable = 1

fb1_framebuffer_num = 2
fb1_format = 10
fb1_pixel_sequence = 0
fb1_scaler_mode_enable = 1
lcd[0/1] configuration

lcd0 is used when lcd output is selected by display screen0, lcd1 by display screen1.
lcd_used: 0 to disable; 1 to enable
lcd_pwm_not_used: 0 to enable PWM; 1 to disable
lcd_pwm_ch: PWM channel
lcd_pwm_freq: PWM frequency in Hz
lcd_pwm_pol: PWM polarity; 0 is pulse LOW for lcd[0|1]_backlight periods, 1 is pulse HIGH.
lcd_x: X-axis active width
lcd_y: Y-axis active height
lcd_dclk_freq: pixel clock frequency in MHz
lcd_if: lcd interface:
interface lcd_interface
0 hv (sync + de)
1 8080
2 ttl
3 lvds
4 dsi (on A20 it means the use of SSD2828 bridge chip, on A31 it might really mean native DSI)
5 edp
6 external dsi (the use of SSD2828 bridge chip on A31 and onwards)
lcd_hbp: hsync back porch
lcd_ht: hsync total cycle
lcd_vbp: vsync back porch
lcd_vt: vsync total cycle * 2
lcd_hv_if: 0 for parallel hv interface; 1: for serial hv interface
lcd_hv_smode: 0 for RGB888 serial interface mode; 1 for CCIR656
lcd_hv_s888_if: serial RGB format
lcd_hv_syuv_if: serial YUV format
lcd_hv_vspw: vysnc plus width
lcd_hv_hspw: hsync plus width
lcd_hv_lde_used: 0 to disable; 1 to enable
lcd_hv_lde_iovalue: HV LDE iovalue
lcd_lvds_ch: 0 for single channel; 1 for dual channel
lcd_lvds_mode: 0 for NS mode; 1 for JEIDA mode
lcd_lvds_bitwidth: 0 for 24 bit; 1 for 18 bit
lcd_io_cfg0: lcd IO configuration
lcd_lvds_io_cross: 0 for normal; 1 for pn cross
lcd_cpu_if: cpu if mode:
mode cpu_if
0 18 bit
1 16 bit mode0
2 16 bit mode1
3 16 bit mode2
4 16 bit mode3
5 9 bit
6 8 bit, 256k
7 8 bit, 65k
lcd_gamma_correction_en: 0 to disable; 1 to enable
lcd_gamma_tbl_[0-255]: Gamma table 0 through 255
lcd_frm: 0 to disable dither; 1 to enable enable rgb666 dither; 2 to enable rgb656 dither
lcd_io_cfg0: lcd io inv
lcd_bl_en_used: 0 to disable; 1 to enable
lcd_bl_en: LCD BackLight GPIO configuration
lcd_power_used: 0 to disable; 1 to enable
lcd_power: LCD_VCC Voltage control GPIO configuration
lcd_pwm_used: 0 to disable; 1 to enable
lcd_pwm: lcd PWM, GPIO configuration (PWM0 fixed using the PB02 PWM1 fixed PI03 without user modification)
lcd_gpio_0: 2/3-wire SCL GPIO configuration
lcd_gpio_1: 2/3-wire SDA GPIO configuration
lcd_gpio_2: 2/3-wire SCEN GPIO configuration
lcd_gpio_3: LCD module RESET GPIO configuration
lcdd0: data bit 0 GPIO configuration
lcdd1: data bit 1 GPIO configuration
lcdd2: data bit 2 GPIO configuration
lcdd3: data bit 3 GPIO configuration
lcdd4: data bit 4 GPIO configuration
lcdd5: data bit 5 GPIO configuration
lcdd6: data bit 6 GPIO configuration
lcdd7: data bit 7 GPIO configuration
lcdd8: data bit 8 GPIO configuration
lcdd9: data bit 9 GPIO configuration
lcdd10: data bit 10 GPIO configuration
lcdd11: data bit 11 GPIO configuration
lcdd12: data bit 12 GPIO configuration
lcdd13: data bit 13 GPIO configuration
lcdd14: data bit 14 GPIO configuration
lcdd15: data bit 15 GPIO configuration
lcdd16: data bit 16 GPIO configuration
lcdd17: data bit 17 GPIO configuration
lcdd18: data bit 18 GPIO configuration
lcdd19: data bit 19 GPIO configuration
lcdd20: data bit 20 GPIO configuration
lcdd21: data bit 21 GPIO configuration
lcdd22: data bit 22 GPIO configuration
lcdd23: data bit 23 GPIO configuration
lcdclk: LCD Clock GPIO configuration
lcdde: LCD de GPIO configuration
lcdhsync: H sync GPIO configuration
lcdvsync: V sync GPIO configuration
[lcd0_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
[lcd0_para]
lcd_used = 1
lcd_x = 800
lcd_y = 480
lcd_dclk_freq = 33
lcd_pwm_freq = 1000
lcd_pwm_pol = 0
lcd_swap = 0
lcd_if = 0
lcd_hbp = 215
lcd_ht = 1055
lcd_vbp = 34
lcd_vt = 1050
lcd_hv_if = 0
lcd_hv_smode = 0
lcd_hv_s888_if = 0
lcd_hv_syuv_if = 0
lcd_hv_vspw = 0
lcd_hv_hspw = 0
lcd_hv_lde_used = 0
lcd_hv_lde_iovalue = 0
lcd_lvds_ch = 0
lcd_lvds_mode = 0
lcd_lvds_bitwidth = 0
lcd_lvds_io_cross = 0
lcd_cpu_if = 0
lcd_cpu_da = 0
lcd_frm = 0
lcd_io_cfg0 = 0×10000000
lcd_io_cfg1 = 0
lcd_io_strength = 0
lcd_bl_en_used = 1
lcd_bl_en = port: PH07
lcd_power_used = 1
lcd_power = port: PH08
lcd_pwm_used = 1
lcd_pwm = port:PB02
lcd_gpio_0 =
lcd_gpio_1 =
lcd_gpio_2 =
lcd_gpio_3 =
lcdd0 = port:PD00
lcdd1 = port:PD01
lcdd2 = port:PD02
lcdd3 = port:PD03
lcdd4 = port:PD04
lcdd5 = port:PD05
lcdd6 = port:PD06
lcdd7 = port:PD07
lcdd8 = port:PD08
lcdd9 = port:PD09
lcdd10 = port:PD10
lcdd11 = port:PD11
lcdd12 = port:PD12
lcdd13 = port:PD13
lcdd14 = port:PD14
lcdd15 = port:PD15
lcdd16 = port:PD16
lcdd17 = port:PD17
lcdd18 = port:PD18
lcdd19 = port:PD19
lcdd20 = port:PD20
lcdd21 = port:PD21
lcdd22 = port:PD22
lcdd23 = port:PD23
lcdclk = port:PD24
lcdde = port:PD25
lcdhsync = port:PD26
lcdvsync = port:PD27
Other configuration examples for certain panels:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
;lvds 640×480 module name: SG0570EDG
lcd_x = 640
lcd_y = 480
lcd_dclk_freq = 25
lcd_if = 3
lcd_hbp = 114
lcd_ht = 800
lcd_vt = 1050
lcd_vbp = 34
lcd_pwm_freq = 20000
lcd_lvds_bitwidth = 1
lcd_pwm_used = 1
lcd_pwm = port:PB02
lcd_pwm_pol = 0

;RGB 800×480 module name: H-B070D-15C
lcd_x = 800
lcd_y = 480
lcd_dclk_freq = 33
lcd_if = 0
lcd_hbp = 46
lcd_ht = 1055
lcd_vbp = 23
lcd_vt = 1050

;RGB 800×600 module name: H-B080D-24F
lcd_x = 800
lcd_y = 600
lcd_dclk_freq = 40
lcd_if = 0
lcd_hbp = 46
lcd_ht = 1056
lcd_vbp = 23
lcd_vt = 1270

;RGB 480×272 module name: KD43G18-40NB-A11
lcd_x = 480
lcd_y = 272
lcd_dclk_freq = 9
lcd_if = 0
lcd_hbp = 2
lcd_ht = 525
lcd_vbp = 2
lcd_vt = 572

;lvds 1024×600 module name: CLAP101NC01CW?
lcd_x = 1024
lcd_y = 600
lcd_dclk_freq = 52
lcd_if = 3
lcd_hbp = 33
lcd_ht = 1344
lcd_vbp = 23
lcd_vt = 1270

;lvds 1024×768 module name: KD080D3-40NA-A2
lcd_x = 1024
lcd_y = 768
lcd_dclk_freq = 65
lcd_if = 3
lcd_hbp = 160
lcd_ht = 1344
lcd_vbp = 23
lcd_vt = 1612

;lvds 1024×768 module name: LG-LP097X02
lcd_x = 1024
lcd_y = 768
lcd_dclk_freq = 100
lcd_if = 3
lcd_hbp = 480
lcd_ht = 2084
lcd_vbp = 6
lcd_vt = 1600
lcd_lvds_bitwidth = 1
lcd_io_cfg0 = 0×04000000
lcd_frm = 1

lcd_io_cfg0 = 0×10000000
lcd_gamma_correction_en = 0
lcd_gamma_tbl_0 = 0×00000000
lcd_gamma_tbl_1 = 0×00010101
;……..
lcd_gamma_tbl_255 = 0x00ffffff
[lcd1_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
[lcd1_para]
lcd_used = 0

lcd_x = 0
lcd_y = 0
lcd_dclk_freq = 0
lcd_pwm_not_used = 0
lcd_pwm_ch = 0
lcd_pwm_freq = 0
lcd_pwm_pol = 0
lcd_if = 0
lcd_hbp = 0
lcd_ht = 0
lcd_vbp = 0
lcd_vt = 0
lcd_hv_if = 0
lcd_hv_smode = 0
lcd_hv_s888_if = 0
lcd_hv_syuv_if = 0
lcd_hv_vspw = 0
lcd_hv_hspw = 0
lcd_lvds_ch = 0
lcd_lvds_mode = 0
lcd_lvds_bitwidth = 0
lcd_lvds_io_cross = 0
lcd_cpu_if = 0
lcd_frm = 0
lcd_io_cfg0 = 0
lcd_gamma_correction_en = 0
lcd_gamma_tbl_0 = 0×00000000
lcd_gamma_tbl_1 = 0×00010101
;……..
lcd_gamma_tbl_255 = 0x00ffffff

lcd_bl_en_used = 0
lcd_bl_en =

lcd_power_used = 0
lcd_power =

lcd_pwm_used = 0
lcd_pwm = port:PI03

lcd_gpio_0 =
lcd_gpio_1 =
lcd_gpio_2 =
lcd_gpio_3 =

lcdd0 = port:PH00
lcdd1 = port:PH01
lcdd2 = port:PH02
lcdd3 = port:PH03
lcdd4 = port:PH04
lcdd5 = port:PH05
lcdd6 = port:PH06
lcdd7 = port:PH07
lcdd8 = port:PH08
lcdd9 = port:PH09
lcdd10 = port:PH10
lcdd11 = port:PH11
lcdd12 = port:PH12
lcdd13 = port:PH13
lcdd14 = port:PH14
lcdd15 = port:PH15
lcdd16 = port:PH16
lcdd17 = port:PH17
lcdd18 = port:PH18
lcdd19 = port:PH19
lcdd20 = port:PH20
lcdd21 = port:PH21
lcdd22 = port:PH22
lcdd23 = port:PH23
lcdclk = port:PH24
lcdde = port:PH25
lcdhsync = port:PH26
lcdvsync = port:PH27
tv out dac configuration

The TV-Out Digital Analog Converter (DAC) modules the framebuffer to a signal suitable for a TV
[tv_out_dac_para]
dac_used: 0 to disable; 1 to enable
dac0_src: Output source for the DAC:
dac1_src: Output source for the DAC:
dac2_src: Output source for the DAC:
dac3_src: Output source for the DAC:
dac Output source
0 Composite
1 Luma
2 Chroma
3
4 Y
5 Pb
6 Pr
7 None
Configuration example:
?
1
2
3
4
5
6
[tv_out_dac_para]
dac_used = 1
dac0_src = 4
dac1_src = 5
dac2_src = 6
dac3_src = 0
csi gpio configuration

csi_used: 0 to enable; 1 to disable
csi_mode: 0 to sample one csi to one buffer; 1 to sample two csi to one buffer
csi_dev_qty: Quantity of devices linked to the csi interface
csi_twi_id: TWI controller to use
csi_twi_id_b: TWI controller to use for second device
csi_mname: Module name to match the csi device; currently known to work:
csi_mname_b: Module name to match the second csi device; currently known to work:
ov7670
gc0308
gt2005
hi704
hi253
csi_twi_addr: TWI address for the used camera
csi_twi_addr_b: TWI address for the used camera for second device
csi_if: interface:
csi_if_b: interface for second device:
if csi interface
0 hv_8bit
1 hv_16bit
2 hv_24bit
3 bt656 1ch
4 bt656 2ch
5 bt656 4ch
csi_pck: p clock GPIO configuration
csi_ck: clock GPIO configuration
csi_hsync: H-sync GPIO configuration
csi_vsync: V-sync GPIO configuration
csi_hflip: Horizontal frame flip
csi_hflip_b: Horizontal frame flip for second device
csi_vflip: Vertical frame flip
csi_vflip_b: Vertical frame flip for second device
csi_d0: data bit 0 GPIO configuration
csi_d1: data bit 1 GPIO configuration
csi_d2: data bit 2 GPIO configuration
csi_d3: data bit 3 GPIO configuration
csi_d4: data bit 4 GPIO configuration
csi_d5: data bit 5 GPIO configuration
csi_d6: data bit 6 GPIO configuration
csi_d7: data bit 7 GPIO configuration
csi_d8: data bit 8 GPIO configuration
csi_d9: data bit 9 GPIO configuration
csi_d10: data bit 10 GPIO configuration
csi_d11: data bit 11 GPIO configuration
csi_d12: data bit 12 GPIO configuration
csi_d13: data bit 13 GPIO configuration
csi_d14: data bit 14 GPIO configuration
csi_d15: data bit 15 GPIO configuration
csi_reset: Camera reset; the default value, high or low ,depends on the module
csi_power_en: Power enable GPIO configuration
csi_stby: Camera standby GPIO configuration; the default value, high or low ,depends on the module
csi_stby_b: Camera standby GPIO configuration for second device; the default value, high or low ,depends on the module
csi_stby_mode: 0 to not shutdown power at standby; 1 shutdown power at standby
csi_facing: Tells the device if the camera is facing or otherwise. 0 for the back, 1 for the front camera.
csi_facing_b: Same as above.
csi_vflip: Vertical flip; 0: disabled, 1: enabled
csi_hflip: Horizontal flip; 0: disabled, 1: enabled
csi_flash: Camera Flash GPIO configuration
csi_flash_b: Camera Flash GPIO configuration for second device
csi_flash_pol: Flash polarity of flash light; 0 for active low; 1 for active high
csi_flash_pol_b: Flash polarity of flash light for second device; 0 for active low; 1 for active high
csi_af_en: Autofocus enable GPIO configuration
csi_iovdd: Camera module IO power, PMU power supply
csi_iovdd_b: Camera module IO power, PMU power supply for second device
csi_avdd: Camera analog power, PMU power supply
csi_avdd_b: Camera analog power, PMU power supply for second device
csi_dvdd: Camera digital power, PMU power supply
csi_dvdd_b: Camera digital power, PMU power supply for second device
pmu_ldo3: “axp20_pll” or leave empty empty when not using any PMU power supply
pmu_ldo4: “axp20_hdmi” or empty when not using any PMU power supply
[csi0_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[csi0_para]
csi_used = 1
csi_mode = 0
csi_dev_qty = 1
csi_stby_mode = 1

csi_mname = “gc0308″
csi_twi_id = 1
csi_twi_addr =0×42
csi_if = 0
csi_vflip = 0
csi_hflip = 1
csi_iovdd = “”
csi_avdd = “”
csi_dvdd = “”
csi_flash_pol = 1

csi_mname_b = “gt2005″
csi_twi_id_b = 1
csi_twi_addr_b = 0×78
csi_if_b = 0
csi_vflip_b = 0
csi_hflip_b = 0
csi_iovdd_b = “”
csi_avdd_b = “”
csi_dvdd_b = “”
csi_flash_pol_b = 1

csi_pck = port:PE00
csi_ck = port:PE01
csi_hsync = port:PE02
csi_vsync= port:PE03
csi_d0 = port:PE04
csi_d1 = port:PE05
csi_d2 = port:PE06
csi_d3 = port:PE07
csi_d4 = port:PE08
csi_d5 = port:PE09
csi_d6 = port:PE10
csi_d7 = port:PE11
csi_d8 = port:PG04
csi_d9 = port:PG05
csi_d10 = port:PG06
csi_d11 = port:PG07
csi_d12 = port:PG08
csi_d13 = port:PG09
csi_d14 = port:PG10
csi_d15 = port:PG11
csi_reset = port:PH13
csi_power_en = port:PH16
csi_stby = port:PH18
csi_flash =
csi_af_en =
csi_reset_b = port:PH13
csi_power_en_b = port:PH16
csi_stby_b = port:PH19
csi_flash_b =
csi_af_en_b =
[csi1_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[csi1_para]
csi_used = 1
csi_mode = 0
csi_dev_qty = 1
csi_stby_mode = 1

csi_mname = “gc0308″
csi_twi_id = 1
csi_twi_addr =0×42
csi_if = 0
csi_vflip = 0
csi_hflip = 1
csi_iovdd = “”
csi_avdd = “”
csi_dvdd = “”
csi_flash_pol = 1

csi_mname_b = “gt2005″
csi_twi_id_b = 1
csi_twi_addr_b = 0×78
csi_if_b = 0
csi_vflip_b = 0
csi_hflip_b = 0
csi_iovdd_b = “”
csi_avdd_b = “”
csi_dvdd_b = “”
csi_flash_pol_b = 1

csi_pck = port:PG00
csi_ck = port:PG01
csi_d0 = port:PH00
csi_d1 = port:PH01
csi_d2 = port:PH02
csi_d3 = port:PH03
csi_d4 = port:PH04
csi_d5 = port:PH05
csi_d6 = port:PH06
csi_d7 = port:PH07
csi_d8 = port:PH08
csi_d9 = port:PH09
csi_d10 = port:PH10
csi_d11 = port:PH11
csi_d12 = port:PH12
csi_d13 = port:PH13
csi_d14 = port:PH14
csi_d15 = port:PH15
csi_d16 = port:PH16
csi_d17 = port:PH17
csi_d18 = port:PH18
csi_d19 = port:PH19
csi_d20 = port:PH20
csi_d21 = port:PH21
csi_d22 = port:PH22
csi_d23 = port:PH23
csi_hsync = port:PH26
csi_vsync= port:PH27
csi_reset = port:PG13
csi_power_en = port:PG16
csi_stby = port:PG18
csi_flash =
csi_af_en =
csi_reset_b = port:PG13
csi_power_en_b = port:PG16
csi_stby_b = port:PG19
csi_flash_b =
csi_af_en_b =
tv configuration

[tvout_para]
tvout_used: 0 to disable; 1 to enable
tvout_channel_num: Channel number
tv_en: TV encoder GPIO configuration
Configuration example:
?
1
2
3
tvout_used = 1
tvout_channel_num = 1
tv_en = port:PI12
[tvin_para]
tvin_used: 0 to disable; 1 to enable
tvin_channel_num: channel number
Configuration example:
?
1
2
tvin_used = 1
tvin_channel_num = 4
sata configuration

[sata_para]
sata_used: 0 to disable; 1 to enable
sata_power_en: Sata power enable GPIO configuration
Configuration example:
?
1
2
sata_used = 1
sata_power_en = port:PB08
sdmmc configuration

There are several things to notice when configuring the sdmmc controller.
sdc_used: 0 to disable; 1 to enable;?0=????1=???
sdc_detmode: detection mode ???????:
mode detection mode note
0
1 GPIO detection Also configure sdc_det to map to a GPIO ?GPIO???????sdc_det????GPIO??
2 sdc_d3 detection sdc_d3 must be configured as HiZ GPIO and have an external 1 M? pull-down resistor ?SD?D3???????????GPIO????????1M????
3 polling (card cannot be swapped) ???????
4 manually (via the proc file system node)
bus_width: 1 for 1bit; 4 for 4bit (may also be called sdc_bwid?!? verify please)
sdc_d0: data line 0 GPIO configuration
sdc_d1: data line 1 GPIO configuration
sdc_d2: data line 2 GPIO configuration
sdc_d3: data line 3 GPIO configuration
sdc_clk: CLK GPIO configuration
sdc_cmd: CMD GPIO configuration
sdc_det: DET GPIO configuration
sdc_use_wp: 0 is normal operation; 1 is write protect
sdc_wp: Write Protect the GPIO configuration
[mmc0_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
[mmc0_para]
sdc_used = 1
sdc_detmode = 1
bus_width = 4
sdc_d1 = port:PF00
sdc_d0 = port:PF01
sdc_clk = port:PF02
sdc_cmd = port:PF03
sdc_d3 = port:PF04
sdc_d2 = port:PF05
sdc_det = port:PH01
sdc_use_wp = 0
sdc_wp =
[mmc1_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
[mmc1_para]
sdc_used = 1
sdc_detmode = 1
bus_width = 4
sdc_cmd = port:PH22
sdc_clk = port:PH23
sdc_d0 = port:PH24
sdc_d1 = port:PH25
sdc_d2 = port:PH26
sdc_d3 = port:PH27
sdc_det = port:PH2
sdc_use_wp = 0
sdc_wp =
[mmc2_para]
Configuration example:
?
1
2
[mmc2_para]
sdc_used = 0
[mmc3_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
[mmc3_para]
sdc_used = 1
sdc_detmode = 4
bus_width = 4
sdc_cmd = port:PI04
sdc_clk = port:PI05
sdc_d0 = port:PI06
sdc_d1 = port:PI07
sdc_d2 = port:PI08
sdc_d3 = port:PI09
sdc_det =
sdc_use_wp = 0
sdc_wp =
memory stick configuration

[ms_para]
ms_used: 0 to disable; 1 to enable
ms_bs: Bus State signal GPIO configuration
ms_clk: Clock GPIO configuration
ms_d0: Data line 0 GPIO Configuration
ms_d1: Data line 1 GPIO Configuration
ms_d2: Data line 2 GPIO Configuration
ms_d3: Data line 3 GPIO Configuration
ms_det: Stick detection GPIO Configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
[ms_para]
ms_used = 1
ms_bs = port:PH06
ms_clk = port:PH07
ms_d0 = port:PH08
ms_d1 = port:PH09
ms_d2 = port:PH10
ms_d3 = port:PH11
ms_det = port:PH2
sim card configuration

[smc_para]
smc_used: 0 to disable; 1 to enable
smc_rst: Reset GPIO configuration
smc_vppen: VPP enable GPIO configuration
smc_vppp: Programming VPP GPIO configuration
smc_det: SIM Card detect GPIO configuration
smc_vccen: VCC enable GPIO configuration
smc_sck: Serial clock GPIO configuration
smc_sda: Serial data GPIO configurion
Configuration example:
?
1
2
3
4
5
6
7
8
9
[smc_para]
smc_used = 1
smc_rst = port:PH13
smc_vppen = port:PH14
smc_vppp = port:PH15
smc_det = port:PH16
smc_vccen = port:PH17
smc_sck = port:PH18
smc_sda = port:PH19
ps2 configuration

[ps2_0_para]
ps2_used: 0 to disable; 1 to enable
ps2_scl: Serial clock GPIO configuration
ps2_sda: Serial data GPIO configuration
Configuration example:
?
1
2
3
4
[ps2_0_para]
ps2_used = 1
ps2_scl = port:PI20
ps2_sda = port:PI21
[ps2_1_para]
ps2_used: 0 to disable; 1 to enable
ps2_scl: Serial clock GPIO configuration
ps2_sda: Serial data GPIO configuration
Configuration example:
?
1
2
3
4
[ps2_1_para]
ps2_used = 1
ps2_scl = port:PI20
ps2_sda = port:PI21
can bus configuration

[can_para]
can_used: 0 to disable; 1 to enable it
can_tx: transmit GPIO Configuration
can_rx: receive GPIO configuration
Configuration example:
?
1
2
3
4
[Can_para]
can_used = 1
can_tx = port:PA16
can_rx = port:PA17
matrix keyboard

23.1 [keypad_para]

kp_used: 0 to disable; 1 to enable
kp_in_size: column width
kp_out_size: row width
kp_in0: column 0 GPIO Configuration
kp_in1: column 1 GPIO Configuration
kp_in2: column 2 GPIO Configuration
kp_in3: column 3 GPIO Configuration
kp_in4: column 4 GPIO configuration
kp_in5: column 5 GPIO configuration
kp_in6: column 6 GPIO Configuration
kp_in7: column 7 GPIO configuration
kp_out0: row 0 GPIO Configuration
kp_out1: row 1 GPIO Configuration
kp_out2: row 2 GPIO Configuration
kp_out3: row 3 GPIO Configuration
kp_out4: row 4 GPIO configuration
kp_out5: row 5 GPIO configuration
kp_out6: row 6 GPIO Configuration
kp_out7: row 7 GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Keypad_para]
kp_used = 1
kp_in_size = 8
kp_out_size = 8
kp_in0 = port:PH08
kp_in1 = port:PH09
kp_in2 = port:PH10
kp_in3 = port:PH11
kp_in4 = port:PH14
kp_in5 = port:PH15
kp_in6 = port:PH16
kp_in7 = port:PH17
kp_out0 = port:PH18
kp_out1 = port:PH19
kp_out2 = port:PH22
kp_out3 = port:PH23
kp_out4 = port:PH24
kp_out5 = port:PH25
kp_out6 = port:PH26
kp_out7 = port:PH27
USB control flags

usb_used: 0 to disable; 1 to enable
usb_port_type: USB port type:
type usb port type
0 device only
1 host only
2 OTG
usb_detect_type: 0 = no checking; 1 = VBus / id check
usb_controller_type: USB controller type:
type usb controller type
0 Unknown
1 EHCI
2 OHCI
usb_id_gpio:USB ID pin GPIO configuration
usb_det_vbus_gpio: USB detect VBus pin GPIO configuration (VBus is USB speak for the +5V line)
usb_drv_vbus_gpio: USB drive VBus pin GPIO configuration
usb_restrict_gpio:
usb_host_init_state: In host only mode, host port initialization state; 0 do not initialize; 1 initializatie USB
usb_restric_flag:
[usbc0]
Configuration example:
?
1
2
3
4
5
6
7
8
[usbc0]
usb_used = 1
usb_port_type = 2
usb_detect_type = 1
usb_id_gpio = port:PH04
usb_det_vbus_gpio = port:PH05
usb_drv_vbus_gpio = port:PB09
usb_host_init_state = 0
[usbc1]
Configuration example:
?
1
2
3
4
5
6
7
8
[usbc1]
usb_used = 1
usb_port_type = 1
usb_detect_type = 0
usb_id_gpio =
usb_det_vbus_gpio =
usb_drv_vbus_gpio = port:PH06
usb_host_init_state = 1
[usbc2]
Configuration example:
?
1
2
3
4
5
6
7
8
[usbc2]
usb_used = 1
usb_port_type = 1
usb_detect_type = 0
usb_id_gpio =
usb_det_vbus_gpio =
usb_drv_vbus_gpio = port:PH03
usb_host_init_state = 1
USB Device

[usb_feature]
vendor_id: vendor ID
mass_storage_id: mass storage ID
adb_id: android debug bridge ID
manufacturer_name: vendor name
product_name: = product name
serial_number: = serial number
Configuration example:
?
1
2
3
4
5
6
7
[usb_feature]
vendor_id = 0x18d1
mass_storage_id = 0×0001
adb_id = 0×0002
manufacturer_name = “USB Developer”
product_name = “Android”
serial_number = “20080411″
[msc_feature]
vendor_name: vendor name
product_name: product name
release: release version
luns: number of logical units
Configuration example:
?
1
2
3
4
5
[msc_feature]
vendor_name = “USB 2.0″
product_name = “USB Flash Driver”
release = 100
luns = 2
G Sensor configuration

[gsensor_para]
gsensor_used: 0 to disable; 1 to enable
gsensor_name: linux kernel module name to match configuration
gsensor_twi_id: TWI bus ID
gsensor_twi_addr: TWI address
gsensor_int1: interrupt 1 GPIO configuration
gsensor_int2: interrupt 2 GPIO configuration
gsensor_revert_x_flag: (untested)
gsensor_revert_y_flag: (untested)
gsensor_revert_z_flag: (untested)
gsensor_exchange_x_y_flag: (untested)
Configuration example 1:
?
1
2
3
4
5
6
7
[Gsensor_para]
gsensor_used = 1
gsenser_name = “bma250″
gsensor_twi_id = 1
gsensor_twi_addr = 0×18
gsensor_int1 = port:PH00
gsensor_int2 = port:PI10
Configuration example 2:
?
1
2
3
4
5
6
7
[Gsensor_para]
gsensor_used = 1
gsenser_name = “bma222″
gsensor_twi_id = 1
gsensor_twi_addr = 0×08
gsensor_int1 = port:PH00
gsensor_int2 = port:PI10
Configuration example 3:
?
1
2
3
4
5
6
7
[Gsensor_para]
gsensor_used = 1
gsenser_name = “mma7660″
gsensor_twi_id = 1
gsensor_twi_addr = 0x4c
gsensor_int1 = port:PH00
gsensor_int2 = port:PI10
gps gpio configuration

[gps_para]
gps_used: 0 to disable; 1 to enable
gps_spi_id: SPI controller; 0 – 2 for SPI0, SPI1 or SPI2; 15 if no SPI is used
gps_spi_cs_num: chip select SPI controller; 0 = SPI0, 1 = SPI1
gps_lradc: 0 or 1 for Low Rate ADC Format; 2 for no Low Rate ADC Format
gps_clk: Clock GPIO configuration
gps_sign: GPS sign GPIO configuration
gps_mag: GPS Magnitude GPIO configuration
gps_vcc_en: GPS VCC enable GPIO configuration
gps_osc_en: GPS Oscillator enable GPIO configuration
gps_rx_en: GPS receive enable GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
[gps_para]
gps_used = 0
gps_spi_id = 2
gps_spi_cs_num = 0
gps_lradc = 1
gps_clk = port:PI00
gps_sign = port:PI01
gps_mag = port:PI02
gps_vcc_en = port:PC22
gps_osc_en = port:PI14
gps_rx_en = port:PI15
sdio wifi configuration

[sdio_wifi_para]
sdio_wifi_used: 0 to disable; 1 to enable
sdio_wifi_sdc_id: SD controller ID to use
sdio_wifi_mod_sel: SDI module selection (see mmc_pm.c ):
mode wifi selection mode note
0 none
1 swl-n20 WiFi
2 usi bm-01 WiFi – Bluetooth – FM radio
3 ar6302qfn
4 apm6xxx
5 swb b23 WiFi – Bluetooth – FM radio
6 hw-mw269x Huawei wifi driver
7 bcm40181
8 bcm40183 BCM40183(BCM4330)
9 rtl8723as RTL8723AS(RF-SM02B)
10 rtl8189es RTL8189ES(SM89E00)
sdio_wifi_shdn: SHDN GPIO configuration
sdio_wifi_host_wakeup: WiFi wakeup GPIO Configuration
sdio_wifi_vdd_en: VDD enable GPIO configuration
sdio_wifi_vcc_en: VCC enable GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
[Sdio_wifi_para]
sdio_wifi_used = 1
sdio_wifi_sdc_id = 3
sdio_wifi_mod_sel = 1

sdio_wifi_shdn = port:PH09
sdio_wifi_host_wakeup = port:PH10
sdio_wifi_vdd_en = port:PH11
sdio_wifi_vcc_en = port:PH12
Optionally the following parameters can be used when other/multiple transceivers are installed.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
; 1 – samsung swl-n20 sdio wifi gpio config
swl_n20_shdn = port:PH09
swl_n20_host_wakeup = port:PH10
swl_n20_vdd_en = port:PH11
swl_n20_vcc_en = port:PH12

; 2 – usi bm01a sdio wifi gpio config
usi_bm01a_wl_pwr = port:PH12
usi_bm01a_wlbt_regon = port:PI11
usi_bm01a_wl_rst = port:PI10
usi_bm01a_wl_wake = port:PI12
usi_bm01a_bt_rst = port:PB05
usi_bm01a_bt_wake = port:PI20
usi_bm01a_bt_hostwake = port:PI21

; 3 – ar6302qfn sdio wifi gpio config
ar6302_qfn_pwr = port:PH12
ar6302_qfn_shdn_n = port:PH09

; 4 – apm sdio wifi gpio config
apm_6981_vcc_en = port:PA09
apm_6981_vdd_en = port:PA10
apm_6981_wakeup = port:PA11
apm_6981_rst_n = port:PA12
apm_6981_pwd_n = port:PA13

; 6 – huawei mw269x(v1/v2) sdio wifi gpio config
hw_mw269x_wl_pwr = port:PH12
hw_mw269x_wl_enb = port:PH11
hw_mw269x_wl_hostwake = port:PH10
hw_mw269x_wl_wake = port:PH09
hw_mw269x_bt_enb = port:PB05
hw_mw269x_bt_wake = port:PI20
hw_mw269x_bt_hostwake = port:PI21
us wifi configuration

[usb_wifi_para]
usb_wifi_used: 0 to disable; 1 to enable
usb_wifi_usbc_num: USB controller to which USB wifi module is connected
usb_host_init_state: used together, such as xx = 2. Then usbc2 the usb_host_init_state 0
Configuration example:
?
1
2
3
[usb_wifi_para]
usb_wifi_used = 0
usb_wifi_usbc_num = 2
3G configuration

[3g_para]
3g_used: 0 to disable; 1 to enable
3g_usbc_num: USB controller to which the 3G module is connected
3g_uart_num: UART controller to which the 3G module is connected
3g_pwr: power enable GPIO configuration
3g_wakeup: wakeup GPIO configuration
3g_int: interrupt GPIO configuration
Configuration example:
?
1
2
3
4
5
6
3g_used = 1
3g_usbc_num = 2
3g_uart_num = 0
3g_pwr = port:PH09
3g_wakeup = port:PH10
3g_int = port:PH11
gyroscope

[gy_para]
gy_used: 0 to disable; 1 to enable
gy_twi_id: TWI controller to use
gy_twi_addr: TWI address to use
gy_int1: interrupt 1 GPIO configuration
gy_int2: interrupt 2 GPIO configuration
Configuration example:
?
1
2
3
4
5
6
[gy_para]
gy_used = 1
gy_twi_id = 1
gy_twi_addr = 0x0a
gy_int1 = port:PH18
gy_int2 = port:PH19
light sensor

[ls_para]
ls_used: 0 to disable; 1 to enable
ls_twi_id: TWI controller to use
ls_twi_addr: TWI address
ls_int: interrupt GPIO configuration
Configuration example:
?
1
2
3
4
5
[ls_para]
ls_used = 1
ls_twi_id = 1
ls_twi_addr = 0x0c
ls_int = port:PH20
compass

[compass_para]
compass_used: 0 to disable; 1 to enable
compass_twi_id: TWI controller to use
compass_twi_addr: TWI address to use
compass_int: interrupt GPIO configuration
Configuration example:
?
1
2
3
4
5
[compass_para]
compass_used = 0
compass_twi_id = 1
compass_twi_addr = 0x0d
compass_int = port:PI13
blue tooth

[bt_para]
bt_used: 0 to disable; 1 to enable
bt_uart_id: UART controller to use
bt_wakeup: wakeup GPIO configuration
bt_gpio: optional bluetooth pin GPIO configuration
bt_rst: = reset GPIO configuration
Configuration example:
?
1
2
3
4
5
6
[Bt_para]
bt_used = 1
bt_uart_id = 2
bt_wakeup = port:PI20
bt_gpio = port:PI21
bt_rst = port:PB05
i2s configuration

[i2s_para]
i2s_used: 0 to disable; 1 to enable
i2s_channel: channel control; 1 for one, 2 for two channels
i2s_mclk: master clock signal GPIO configuration
i2s_bclk: bit clock signal GPIO configuration
i2s_lrclk: word clock (left/right) signal GPIO configuration
i2s_dout0: digital out 0 GPIO configuration
i2s_dout1: (optional) digital out 1 GPIO configuration
i2s_dout2: (optional) digital out 2 GPIO configuration
i2s_dout3: (optional) digital out 3 GPIO configuration
i2s_din: multiplexed in signal GPIO configuration
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
[i2s_para]
i2s_used = 1
i2s_channel = 2
i2s_mclk = port:PB05
i2s_bclk = port:PB06
i2s_lrclk = port:PB07
i2s_dout0 = port:PB08
i2s_dout1 =
i2s_dout2 =
i2s_dout3 =
i2s_din = port:PB12
spdif configuration

[spdif_para]
spdif_used: 0 to disable; 1 to enable
spdif_mclk: optional master clock GPIO configuration
spdif_dout: digital out GPIO configuration
spdif_din: digital in GPIO configuration
Configuration example:
?
1
2
3
4
5
[spdif_para]
spdif_used = 1
spdif_mclk =
spdif_dout = port:PB13
spdif_din =
audio configuration

[audio_para]
audio_used: 0 to disable; 1 to enable
audio_pa_ctrl: External Amp shutdown GPIO configuration
audio_lr_change: 0 for normal operation; 1 to swap left and right channels
playback_used: 0 to disable; 1 to enable This is a linux-sunxi specific extention
capture_used: 0 to dissable; 1 to enable This is a linux-sunxi specific extention
Some extra settings were introduced with the A31:
audio_mute_ctrl: External Amp mute GPIO configuration
cap_vol: ???
headphone_vol: Internal headphone amp volume (0 ~ 0x3f: 0 .. -62 dB)
headphone_direct_used: 1 for headphone DC direct drive (no coupling capacitors)
headset_mic_vol: Headset microphone boost gain (0 ~ 0×7: 0 dB, 24 .. 42 dB)
main_mic_vol: Main microphone boost gain (0 ~ 0×7: 0 dB, 24 .. 42 dB)
pa_double_used: 0 for mono differential output; 1 for stereo output
pa_double_vol: Line out volume for Stereo output mode
pa_single_vol: Line out volume for Mono differential output mode
Configuration example:
?
1
2
3
4
5
6
[audio_para]
audio_used = 1
audio_pa_ctrl = port:PH15
audio_lr_change = 0
playback_used = 1
capture_used = 1
infrared remote configuration

[ir_para]
ir_used: 0 to disable; 1 to enable
ir0_rx: receiver GPIO configuration
ir0_tx: transmitter GPIO configuration
ir1_rx: receiver GPIO configuration
ir1_tx: transmitter GPIO configuration
Configuration example:
?
1
2
3
4
5
6
ir_used = 1
ir0_tx = port:PB03default
ir0_rx = port:PB04default

ir1_tx = port:PB22default
ir1_rx = port:PB23default
pmu configuration

[pmu_para]
pmu_used: 0 to disable; 1 to enable
pmu_used2: 0 to disable; 1 to enable secondary PMU
pmu_twi_id: TWI controller to use
pmu_twi_addr: TWI address to use
pmu_irq_id: interrupt to use; 0 = NMI; 1 – 15 = interrupt 1 to 15
pmu_battery_rdc: battery internal resistance in m?
pmu_battery_cap: battery capacity in mAh
pmu_init_chgcur: initial charging current in mA; 300, 400 … 1800
pmu_init_chgcur2: initial charging current in mA for secondary PMU; 300, 400 … 1800
pmu_earlysuspend_chgcur2 early suspend charging current in mA; 300, 400 … 1800
pmu_suspend_chgcur: suspended charging current in mA; 300, 400 … 1800
pmu_suspend_chgcur2: suspended charging current in mA for secondary PMU; 300, 400 … 1800
pmu_resume_chgcur: normal charging current in mA; 300, 400 … 1800
pmu_resume_chgcur2: normal charging current in mA for secondary PMU; 300, 400 … 1800
pmu_shutdown_chgcur: powered down charge current in mA; 300, 400 … 1800
pmu_shutdown_chgcur2: powered down charge current in mA for secondary PMU; 300, 400 … 1800
pmu_init_chgvol: initial charging target voltage in mV; 4100/4150/4200/4360
pmu_init_chgend_rate: initial charging current ratio in %; 10, 15
pmu_init_chg_enabled: 0 to disable; 1 to enable
pmu_init_adc_freq: initial ADC sampling rate in Hz; 25/50/100/200
pmu_init_adc_freqc: initial ADC coulomb meter sampling rate in Hz; 25/50/100/200
pmu_init_chg_pretime: initial precharge timeout in minutes; 40/50/60/70
pmu_init_chg_csttime: initial constant charging current timeout in minutes; 360/480/600/720
pmu_bat_para1: = battery charge LUT in %
pmu_bat_para2: = battery charge LUT in %
pmu_bat_para3: = battery charge LUT in %
pmu_bat_para4: = battery charge LUT in %
pmu_bat_para5: = battery charge LUT in %
pmu_bat_para6: = battery charge LUT in %
pmu_bat_para7: = battery charge LUT in %
pmu_bat_para8: = battery charge LUT in %
pmu_bat_para9: = battery charge LUT in %
pmu_bat_para10: = battery charge LUT in %
pmu_bat_para11: = battery charge LUT in %
pmu_bat_para12: = battery charge LUT in %
pmu_bat_para13: = battery charge LUT in %
pmu_bat_para14: = battery charge LUT in %
pmu_bat_para15: = battery charge LUT in %
pmu_bat_para16: = battery charge LUT in %; should always be 100
pmu_usbvol_limit: 0 no USB voltage limiter; 1 = limit USB voltage
usb pmu_usbvol: USB voltage limit in mV; 4000, 4100 … 4700
pmu_usbcur_limit: 0 no USB current limiter; 1 = limit USB current
pmu_usbcur: USB current limit in mA; 100/500/900
pmu_pwroff_vol: boot hardware protection voltage in mV; 2600, 2700 … 3300
pmu_pwron_vol: running hardware protection voltage in mV; 2600, 2700 … 3300
pmu_pekoff_time: Power Enable Key, short power button off delay in ms; 4000, 6000, 8000, 10000
pmu_pekoff_en: 0 to disable; 1 to enable power button power off
pmu_peklong_time: long power off button delay in ms; 1000, 1500, 2000, 2500
pmu_pekon_time: power on button delay in ms; 128, 1000, 2000, 3000
pmu_pwrok_time: power ‘ok’ delay in ms; 8, 64
pmu_pwrnoe_time: n_oe from low to high shutdown delay time in ms; 128, 1000, 2000, 3000
pmu_intotp_en: 0 to disable; 1 to enable over temperature protection
pmu_suspendpwroff_vol: shutdown voltage when suspended and battery is low
pmu_batdeten: Battery detection enabled
pmu_adpdet: adapter detect GPIO configuration
pmu_backupen: 1 to enable RTC/backup battery charging
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
[pmu_para]
pmu_used = 1
pmu_twi_addr = 0×34
pmu_twi_id = 0
pmu_irq_id = 0
pmu_battery_rdc = 200
pmu_battery_cap = 2600
pmu_init_chgcur = 300
pmu_suspend_chgcur = 1000
pmu_resume_chgcur = 300
pmu_shutdown_chgcur = 1000
pmu_init_chgvol = 4200
pmu_init_chgend_rate = 15
pmu_init_chg_enabled = 1
pmu_init_adc_freq = 100
pmu_init_adc_freqc = 100
pmu_init_chg_pretime = 50
pmu_init_chg_csttime = 720
pmu_bat_para1 = 0
pmu_bat_para2 = 0
pmu_bat_para3 = 1
pmu_bat_para4 = 5
pmu_bat_para5 = 7
pmu_bat_para6 = 13
pmu_bat_para7 = 16
pmu_bat_para8 = 26
pmu_bat_para9 = 36
pmu_bat_para10 = 46
pmu_bat_para11 = 53
pmu_bat_para12 = 61
pmu_bat_para13 = 73
pmu_bat_para14 = 84
pmu_bat_para15 = 92
pmu_bat_para16 = 100
pmu_usbvol_limit = 1
pmu_usbvol = 4400
pmu_usbcur_limit = 1
pmu_usbcur = 900
pmu_pwroff_vol = 3300
pmu_pwron_vol = 2900
pmu_pekoff_time = 6000
pmu_pekoff_en = 1
pmu_peklong_time = 1500
pmu_pekon_time = 1000
pmu_pwrok_time = 64
pmu_pwrnoe_time = 2000
pmu_intotp_en = 1
pmu_adpdet = port:PH02
pmu_batdeten = 1
pmu_suspendpwroff_vol = 3500

pmu_used2 = 0
pmu_init_chgcur2 = 400
pmu_suspend_chgcur2 = 1200
pmu_resume_chgcur2 = 400
pmu_shutdown_chgcur2 = 1200
recovery key configuration

[recovery_key]
key_min: minimal length for the key to be depressed in seconds
key_max: maximal length for the key to be depressed in seconds
Example configuration:
?
1
2
key_min = 4
key_max = 32
dvfs voltage-frequency table configuration

Define at which frequency what voltage should be set. Recommended defaults:
voltage frequency range
1.50 v 1008 MHz – 1056 MHz
1.40 v 912 MHz – 1008 MHz
1.35 v 864 MHz – 912 MHz
1.30 v 624 MHz – 864 MHz
1.25 v 60 MHz – 624 MHz
[dvfs_table]
max_freq: cpu maximum frequency in Hz; can not be more than 1008 MHz
min_freq: cpu minimum frequency in Hz; can not be less than 60 MHz
lv_count: number of lv_freq/lv_volt pairs; must be < 16
lv1_freq: state 1 frequency
lv1_volt: state 1 voltage
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[dvfs_table]
max_freq = 1008000000
min_freq = 60000000
lv_count = 5

lv1_freq = 1056000000
lv1_volt = 1500

lv2_freq = 1008000000
lv2_volt = 1400

lv3_freq = 912000000
lv3_volt = 1350

lv4_freq = 864000000
lv4_volt = 1300

lv5_freq = 624000000
lv5_volt = 1250
led configuration

LEDs are accessible via sys-fs; for example on the cubietruck you can find the following directory: /sys/class/leds/blue\:ph21\:led1 `cat` the file trigger to see the triggers that can be set in .fex files. Currently these are
none (kinda defeats the purpose of setting a trigger)
rfkill0
battery-charging-or-full
battery-charging
battery-full
battery-charging-blink-full-solid
ac-online
usb-online
mmc0
mmc1
timer
heartbeat
cpu0
cpu1
default-on
rfkill1
rfkill2
How much they make sense – experiment. I'd be especially curious about the effects of rfkill settings.
Please note that depending on the trigger in question the sysfs will be populated with even more pseudo files. When you choose timer for example then you get a constant blinking led and two more files: delay_on and delay_off with which you can specify how many milliseconds will the LED stay in on/off state. Very convenient to indicate eg. disk usage or average load with higher blinking frequency and stuff like that.
[leds_para]
Configuration example:
?
1
2
3
4
5
6
7
8
9
10
11
12
[leds_para]
leds_used = 1
leds_num = 3
leds_pin_1 = port:PH20
leds_name_1 = “ph20:green:led1″
leds_trigger_1 = “heartbeat”
leds_pin_2 = port:PH21
leds_name_2 = “ph21:blue:led2″
leds_trigger_2 = “cpu0″
leds_pin_3 = port:PI12
leds_name_3 = “red:pi12:led3″
leds_trigger_3 = “cpu1″
external leds
External LEDs that are connected to one of the GPIO pins (don’t forget to add a resistor!) can also be defined in the fex file and used like internal ones afterwards. You have to check which GPIO pin is connected to which SoC pin and use this in the definition. As an example a 3rd led on a Banana Pro connected to GPIO pin 19 (PI12) in the config above. This will lead to a sysfs entry /sys/class/leds/red:pi12:led3 where everything works just like with internal leds.
dynamic configuration

[dynamic]
Configuration example:
?
1
2
[dynamic]
MAC = “000000000000″
Category: Software

Posted in Uncategorized | Leave a comment

.FEX file Description

A FEX file defines various aspects of how the SoC works. It configures the GPIO pins and sets up DRAM, Display, etc parameters. It is Allwinners predecessor for the devicetree.
Each line consists of a key = value pair combination under a [sectionheader]. All three, [sectionheader], key and value are case-sensitive. For comments a semi-colon (;) is used and everything following a semi-colon is ignored. The chip does not parse a textual version of a fex file, it gets cleaned and compiled by a fex-compiler. A reverse engineerd open source version exists in the sunxi-tools repository. Also a de-compiler which takes a binary script.bin and creates a textual script.fex. Usually, script.bin can be found on the nanda boot partition on A10 devices.
Sticky-note-pin.png Note: The mainline Linux kernel makes no use of FEX / script.bin, and relies on the device tree model instead (.dtb files).

Posted in Uncategorized | Leave a comment

C program to swap two numbers using bitwise operator

/**
* C program to swap two numbers using bitwise operator
*/

#include

int main()
{
int num1, num2;

//Reads two numbers from user
printf(“Enter any two numbers: “);
scanf(“%d%d”, &num1, &num2);

printf(“Original value of num1 = %d\n”, num1);
printf(“Original value of num2 = %d\n”, num2);

num1 ^= num2;
num2 ^= num1;
num1 ^= num2;

printf(“Num1 after swapping = %d\n”, num1);
printf(“Num2 after swapping = %d\n”, num2);

return 0;
}

Posted in Uncategorized | Leave a comment

Serial Interfaces

Serial is an umbrella word for all that is “Time Division Multiplexed”, to use an expensive term. It means that the data is sent spread over time, most often one single bit after another. All the protocols you’re naming are serial protocols.

UART, for Universal Asynchronous Receiver Transmitter, is one of the most used serial protocols. It’s almost as old as I am, and very simple. Most controllers have a hardware UART on board. It uses a single data line for transmitting and one for receiving data. Most often 8-bit data is transferred, as follows: 1 start bit(low level), 8 data bits and 1 stop bit(high level). The low level start bit and high level stop bit mean that there’s always a high to low transition to start the communication. That’s what describes UART. No voltage level, so you can have it at 3.3 V or 5 V, whichever your microcontroller uses. Note that the microcontrollers which want to communicate via UART have to agree on the transmission speed, the bit-rate, as they only have the start bit’s falling edge to synchronize. That’s called asynchronous communication.

For long distance communication (That doesn’t have to be hundreds of meters) the 5 V UART is not very reliable, that’s why it’s converted to a higher voltage, typically +12 V for a “0″ and -12 V for a “1″. The data format remains the same. Then you have RS-232 (which you actually should call EIA-232, but nobody does.)

The timing dependency is one of the big drawbacks of UART, and the solution is USART, for Universal Synchronous/Asynchronous Receiver Transmitter. This can do UART, but also a synchronous protocol. In synchronous there’s not only data, but also a clock transmitted. With each bit a clock pulse tells the receiver it should latch that bit. Synchronous protocols either need a higher bandwidth, like in the case of Manchester encoding, or an extra wire for the clock, like SPI and I2C.

SPI (Serial Peripheral Interface) is another very simple serial protocol. A master sends a clock signal, and upon each clock pulse it shifts one bit out to the slave, and one bit in, coming from the slave. Signal names are therefore SCK for clock, MOSI for Master Out Slave In, and MISO for Master In Slave Out. By using SS (Slave Select) signals the master can control more than 1 slave on the bus. There are two ways to connect multiple slave devices to one master, one is mentioned above i.e. using slave select, and other is daisy chaining, it uses less hardware pins(select lines), but software gets complicated.

I2C (Inter-Integrated Circuit, pronounced “I squared C”) is also a synchronous protocol, and it’s the first we see which has some “intelligence” in it; the other ones dumbly shifted bits in and out, and that was that. I2C uses only 2 wires, one for the clock (SCL) and one for the data (SDA). That means that master and slave send data over the same wire, again controlled by the master who creates the clock signal. I2C doesn’t use separate Slave Selects to select a particular device, but has addressing. The first byte sent by the master holds a 7 bit address (so that you can use 127 devices on the bus) and a read/write bit, indicating whether the next byte(s) will also come from the master of should come from the slave. After each byte receiver must send a “0″ to acknowledge the reception of the byte, which the master latches with a 9th clock pulse. If the master wants to write a byte the same process repeats: the master puts bit after bit on the bus and each time gives a clock pulse to signal that the data is ready to be read. If the master wants to receive data it only generates the clock pulses. The slave has to take care that the next bit is ready when the clock pulse is given. This protocol is patented by NXP(formerly Phillips), to save licensing cost, Atmel using the word TWI(2-wire interface) which exactly same as I2C, so any AVR device will not have I2C but it will have TWI.

Two or more signals on the same wire may cause conflicts, and you would have a problem if one device sends a “1″ while the other sends a “0″. Therefore the bus is wired-OR’d: two resistors pull the bus to a high level, and the devices only send low levels. If they want to send a high level they simply release the bus.

TTL (Transistor Transistor Logic) is not a protocol. It’s an older technology for digital logic, but the name is often used to refer to the 5 V supply voltage, often incorrectly referring to what should be called UART.

Posted in Uncategorized | Leave a comment

ARM and Thumb instruction set overview

All ARM instructions are 32 bits long. Instructions are stored word-aligned, so the least significant two bits of instruction addresses are always zero in ARM state.

Thumb instructions are either 16 or 32 bits long. Instructions are stored half-word aligned. Some instructions use the least significant bit of the address to determine whether the code being branched to is Thumb code or ARM code.
Before the introduction of 32-bit Thumb instructions, the Thumb instruction set was limited to a restricted subset of the functionality of the ARM instruction set. Almost all Thumb instructions were 16-bit. Together, the 32-bit and 16-bit Thumb instructions provide functionality that is almost identical to that of the ARM instruction set.
The following table describes some of the functional groupings of the available instructions:

Posted in Uncategorized | Leave a comment

Cortex-A series processors

ARM documentation set for the ARM Cortex-A family of processors, including the ARM Cortex-A15 MPCore, ARM Cortex-A9 MPCore, ARM Cortex-A9 single core, ARM Cortex-A8, ARM Cortex-A7 MPCore, and ARM Cortex-A5 processors.

The ARM Cortex-A Series is a family of applications processors for complex OS and user applications. The Cortex-A family processors support the ARM and Thumb instruction sets, incorporating Thumb 2-technology.

The ARM Cortex-A15 MPCore processor has an out-of-order superscalar pipeline with a tightly-coupled low-latency level-2 cache that can be up to 4MB in size. The Cortex-A15 MPCore processor implements the ARMv7-A architecture profile.

The ARM Cortex-A9 processor is a very high-performance, low-power, ARM macrocell with an L1 cache subsystem that provides full virtual memory capabilities. The Cortex-A9 processor implements the ARMv7-A architecture profile and can execute 32-bit ARM instructions, 16-bit and 32-bit Thumb instructions, and 8-bit Java bytecodes in Jazelle state.

The ARM Cortex-A8 processor is a high-performance, low-power, cached application processor that implements the ARMv7-A architecture profile and provides full virtual memory capabilities.

The ARM Cortex-A7 MPCore processor is fully compatible with other Cortex-A family of processors and incorporates all of the features of the high-performance Cortex-A15 MPCore processor including virtualization, Large Physical Address Extension (LPAE), NEON Media Processing Engine (MPE) Advanced SIMD, and AMBA 4 ACE coherency support. The Cortex-A7 MPCore processor implements the ARMv7-A architecture profile.

The ARM Cortex-A5 processor is a high-performance, low-power, ARM macrocell with an L1 cache subsystem that provides full virtual memory capabilities. The Cortex-A5 processor implements the ARMv7-A architecture profile and can execute 32-bit ARM instructions and 16-bit and 32-bit Thumb instructions. The Cortex-A5 is the smallest member of the Cortex-A processor family.

Posted in Uncategorized | Leave a comment

Multiline macros in C (macro as function)

Multiline macros in C
In this article, we will discuss how to write a multi-line macro. We can write multi-line macro same like function, but each statement ends with “\”. Let us see with example. Below is simple macro, which accepts input number from user, and prints whether entered number is even or odd.

#include

#define MACRO(num, str) {\
printf(“%d”, num);\
printf(” is”);\
printf(” %s number”, str);\
printf(“\n”);\
}

int main(void)
{
int num;

printf(“Enter a number: “);
scanf(“%d”, &num);

if (num & 1)
MACRO(num, “Odd”);
else
MACRO(num, “Even”);

return 0;
}
At first look, the code looks OK, but when we try to compile this code, it gives compilation error.

[shubham@/media/partition/GFG]$ make macro
cc macro.c -o macro
macro.c: In function ‘main’:
macro.c:19:2: error: ‘else’ without a previous ‘if’
make: *** [macro] Error 1
[shubham@/media/partition/GFG]$
Let us see what mistake we did while writing macro. We have enclosed macro in curly braces. According to C-language rule, each C-statement should end with semicolon. That’s why we have ended MACRO with semicolon. Here is a mistake. Let us see how compile expands this macro.

if (num & 1)
{
————————-
—- Macro expansion —-
————————-
}; /* Semicolon at the end of MACRO, and here is ERROR */

else
{
————————-
—- Macro expansion —-
————————-

};
We have ended macro with semicolon. When compiler expands macro, it puts semicolon after “if” statement. Because of semicolon between “if and else statement” compiler gives compilation error. Above program will work fine, if we ignore “else” part.

To overcome this limitation, we can enclose our macro in “do-while(0)” statement. Our modified macro will look like this.

#include

#define MACRO(num, str) do {\
printf(“%d”, num);\
printf(” is”);\
printf(” %s number”, str);\
printf(“\n”);\
} while(0)

int main(void)
{
int num;

printf(“Enter a number: “);
scanf(“%d”, &num);

if (num & 1)
MACRO(num, “Odd”);
else
MACRO(num, “Even”);

return 0;
}

Compile and run above code, now this code will work fine.

[shubham@/media/partition/GFG]$ make macro
cc macro.c -o macro
[shubham@/media/partition/GFG]$ ./macro
Enter a number: 9
9 is Odd number
[shubham@/media/partition/GFG]$ ./macro
Enter a number: 10
10 is Even number
[shubham@/media/partition/GFG]$
We have enclosed macro in “do – while(0)” loop and at the end of while, we have put condition as “while(0)”, that’s why this loop will execute only one time.

Similarly, instead of “do – while(0)” loop we can enclose multi-line macro in parenthesis. We can achieve the same result by using this trick. Let us see example.

#include

#define MACRO(num, str) ({\
printf(“%d”, num);\
printf(” is”);\
printf(” %s number”, str);\
printf(“\n”);\
})

int main(void)
{
int num;

printf(“Enter a number: “);
scanf(“%d”, &num);

if (num & 1)
MACRO(num, “Odd”);
else
MACRO(num, “Even”);

return 0;
}
Run on IDE
[shubham@/media/partition/GFG]$ make macro
cc macro.c -o macro
[shubham@/media/partition/GFG]$ ./macro
Enter a number: 10
10 is Even number
[shubham@/media/partition/GFG]$ ./macro
Enter a number: 15
15 is Odd number
[shubham@/media/partition/GFG]$

Posted in Uncategorized | Leave a comment