Author Topic: Accessing cubietruck registers  (Read 2604 times)

Offline aleale97

  • Newbie
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Accessing cubietruck registers
« on: January 25, 2015, 04:14:46 pm »
Hi all!
I want to use Cubietruck as controller for a robot and i would like to write code in a bare-metal (or similar) variant.
I tryied accessing register but i still can't get a PWM output, here is my code:

Code: [Select]
/* Author: Alessandro Rossetti */
/* Closing in: 25/01/2015 */
using namespace std;
#include <iostream>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <iomanip>

#define PWM_PAGE 0x1C20000
#define PWM_OFFSET 0xE00
#define PWM_LENGHT PWM_OFFSET+0xB

#define CH0_ENABLE 16
#define CH1_ENABLE 524288

#define CH0_PULSESTART 256
#define CH1_PULSESTART 8388608

#define LOWSPEED 393228
#define DONTMASK 2097216
#define ACTIVEHIGH 1048608

void printLine(char testo[50]) {
    int lenght = strlen(testo);
    int toAdd = (50 - lenght) / 2 - 2;
    for (int cnt=0; cnt < toAdd; cnt++) {
        cout << '-';
    }
    cout << " " << testo << " ";
    for (int cnt=0; cnt < toAdd; cnt++) {
        cout << '-';
    }
    cout << endl;
}

int main() {
   
    int *ctrl;
    int *ch0, *ch1;
   
    //Opening file
    int MemFile = open("/dev/mem", O_RDWR | O_SYNC);
    if (!MemFile) return 1;
   
    //Mapping memory
    void *mapped = mmap(NULL, PWM_LENGHT, PROT_READ | PROT_WRITE, MAP_SHARED, MemFile, PWM_PAGE);
    if (mapped == MAP_FAILED) return 2;

    //Adding offset
    mapped += PWM_OFFSET;
   
    //Initializing pointers
    ctrl = (int *) mapped;
    ch0 = (int *) (mapped + 4);
    ch1 = (int *) (mapped + 8);

    //Output of mapped addresses
    printLine("Addresses");
    cout << "Control Register: " << ctrl << endl;
    cout << "CH0 : " << ch0 << endl;
    cout << "CH1 : " << ch1 << endl;
    printLine("");
   
    //Print of Values
    printLine("Values");
    cout << "Control Register: " << *ctrl << endl;
    cout << "CH0 : " << *ch0 << endl;
    cout << "CH1 : " << *ch1 << endl;
    printLine("");
   
    //Assign
    *ch0 = 65538;
    *ch1 = 131073;
    *ctrl = 0 | CH0_ENABLE | CH1_ENABLE | CH0_PULSESTART | CH1_PULSESTART | LOWSPEED | DONTMASK | ACTIVEHIGH;
   
    //Print after CTRL setup
    printLine("After CTRL Setup");
    cout << "Control Register: " << *ctrl << endl;
    cout << "Should be: " << (0 | CH0_ENABLE | CH1_ENABLE | CH0_PULSESTART | CH1_PULSESTART | LOWSPEED | DONTMASK | ACTIVEHIGH) << endl;
    cout << "CH0 : " << *ch0 << endl;
    cout << "CH1 : " << *ch1 << endl;
    printLine("");
   
    //Exit
    munmap(mapped-PWM_OFFSET, PWM_LENGHT);
    close(MemFile);
    return 0;

I got the registers values (set in defines) from the A20 User Manual but no PWM output even with this output given by the program:

Code: [Select]
------------------ Addresses ------------------
Control Register: 0xb6efee00
CH0 : 0xb6efee04
CH1 : 0xb6efee08
-----------------------  -----------------------
-------------------- Values --------------------
Control Register: 111
CH0 : 157221416
CH1 : 0
-----------------------  -----------------------
--------------- After CTRL Setup ---------------
Control Register: 12452220
Should be: 12452220
CH0 : 65538
CH1 : 131073
-----------------------  -----------------------

Can anyone find the problem? I'm stuck on it from 3 days ahah
Ill hook up an oscilloscope on thoose pins (CN8-> 21/19)to see if there is something that my logic analyzer doesn't get but i don't feel as lucky... I will try to access GPIO registers too, just to see if i can light up a led and confirm the mmap is working correctly.

Good luck for thoose who will try, Alessandro.

Offline Goatfreed

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
    • View Profile
Re: Accessing cubietruck registers
« Reply #1 on: January 27, 2015, 02:36:35 am »
Hi,

I don't really have experience with PWM.
But I cannot see in your code, that you would enable the clock for CH0 and CH1.
You might have to take a look in the CCU register (base 0x01C2 0118) with offsets LCD0_CH0 0x0118, LCD1_CH0 0x011C, LCD0_CH1 0x012C and CLD1_CH1 0x0130.
When you select the source clock (standard is PLL3) you might also need to enable that clock first.
For PLL3 it would be in CCU registers at offset 0x10 (it is called "-Video 0" so might be, what you are looking for).
Also there is the AHB Clock Gating Register 1 at offset 0x064 where there is LCD0/1 gating disabled by default.
I don't know how these work together, unfortunatelly.

I am not sure, if you can "simply" modify the CCU registers, as I only used OSC24M for now, which is enabled by default.
I actually do have trouble right now, trying to change the CPU clock to PLL1...

As sayed i have not used PWM at all, so I have not tried this.
Therefore, if you succeed, would you please post the code snippet?


By the way. Accessing the register can be done as easy as:
*((unsigned int)(PWM_PAGE+PWM_OFFSET)) |= <whatever>.
« Last Edit: January 27, 2015, 06:22:28 am by Goatfreed »

Offline aleale97

  • Newbie
  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Re: Accessing cubietruck registers
« Reply #2 on: February 08, 2015, 05:21:29 pm »
Thx for the help, i'm going to attach to this post the GPIO library for cubietruck that i wrote and tested. Its not meant for beginners but it is working  :)

Ill see this register you say even if it seems that with defaults i should have output anyway. ;)