PXA270 GPIO (комплект разработчика eSOM270 / SPARK) - Windows CE 6.0 R2 - PullRequest
0 голосов
/ 15 января 2011

Я пытаюсь прочитать до 6 входов и записать до 4 выходов, используя GPIO ... это относительно простое приложение (или я так думал), но я просто не могу пройти мимо Win CE, останавливая мое приложение с помощьючто выглядит как ошибка нарушения доступа к памяти всякий раз, когда я пытаюсь обратиться к выводу GPIO - даже просто настраивая направление вывода (вход или выход), не говоря уже о чтении или записи, используя GLPR0 / 1/2/3, GPCR0 / 1/2/ 3, GPSR) / 1/2/3 и т. Д.

Я, должно быть, что-то здесь упустил, но не вижу, что - приложение является частью УПРАВЛЕНИЯ РЕЛЕ НАСОСА I / O с:

  • 6 х входов
  • 4 х выходов
  • Код драйвера низкого уровня, поток постоянно зацикливает чтение значений 6 входов, записывает значения в регистры состояния / память-сопоставленные адреса для приложения с графическим интерфейсом для чтения (защелкиваются).
  • Каждые ~ 1 сек. GUI считывает вышеуказанные 6 входов, затем вызывает низкоуровневую функцию драйвера для очистки 6 входов.

Входные контакты

  • Вход 1 = gpio24
  • Вход 2 = gpio 25
  • Вход 3 = gpio108
  • Вход 4 = gpio93
  • Вход 5 = gpio94
  • Вход 6 = gpio95

Выходные контакты

  • Выход A1 = gpio103
  • Выход A2 = gpio104
  • Выход A3 = gpio105
  • Выход A4 = gpio27

Вот код (ниже, в классе IoRelayControl) для конфигурации / чтения / записи GPIO.Windows CE 6.0 на eSOM270 (PAX270) убивает меня при первом обращении (конфигурация GPIO направления выводов ввода / вывода в функции GPIOConfig ()).

Любой совет, с благодарностью полученный ..

using System;
using System.Text;
using System.Threading;

namespace Sampler
{
    unsafe class IoRelayControl
    {
        const byte GPIO24   = 24;
        const byte GPIO25   = 25;
        const byte GPIO108  = 108;
        const byte GPIO93   = 93;
        const byte GPIO94   = 94;
        const byte GPIO95   = 95;

        const byte GPIO103  = 103;
        const byte GPIO104  = 104;
        const byte GPIO105  = 105;
        const byte GPIO27   = 27;

        const bool INVALID_HANDLE_ERROR = false;
        const byte GPIO_AF_0 = 0;
        const byte GPIO_AF_1 = 1;
        const byte GPIO_AF_2 = 2;
        const byte GPIO_AF_3 = 3;
        const bool GPIO_OUTPUT = true;
        const bool GPIO_INPUT = false;
        const byte NO_GPIO_ERROR = 0;
        const byte CONFIG_FAILED_ERROR = 100;
        const byte SET_FAILED_ERROR = 102;
        const byte FAILED_ERROR = 103;
        const byte GPIO_INVALID_HANDLE = 104;
        const byte READ_FAILED_ERROR = 105;
        const byte INVALID_GPIO_ERROR = 106;

        public volatile UInt32* GPDR0_Address = (UInt32*)0x40E0000C;      // GPIO Pin Direction Register 0
        public volatile UInt32* GPDR1_Address = (UInt32*)0x40E00010;      // GPIO Pin Direction Register 1
        public volatile UInt32* GPDR2_Address = (UInt32*)0x40E00014;      // GPIO Pin Direction Register 2
        public volatile UInt32* GPDR3_Address = (UInt32*)0x40E0010C;      // GPIO Pin Direction Register 3

        public volatile UInt32* GPSR0_Address = (UInt32*)0x40E00018;      // GPIO Pin-Output Set Register 0
        public volatile UInt32* GPSR1_Address = (UInt32*)0x40E0001C;      // GPIO Pin-Output Set Register 1
        public volatile UInt32* GPSR2_Address = (UInt32*)0x40E00020;      // GPIO Pin-Output Set Register 2
        public volatile UInt32* GPSR3_Address = (UInt32*)0x40E00118;      // GPIO Pin-Output Set Register 3

        public volatile UInt32* GPCR0_Address = (UInt32*)0x40E00024;      // GPIO Pin-Output Clear Register 0
        public volatile UInt32* GPCR1_Address = (UInt32*)0x40E0001C;      // GPIO Pin-Output Clear Register 1
        public volatile UInt32* GPCR2_Address = (UInt32*)0x40E00020;      // GPIO Pin-Output Clear Register 2
        public volatile UInt32* GPCR3_Address = (UInt32*)0x40E00118;      // GPIO Pin-Output Clear Register 3

        public volatile UInt32* GAFR0L_Address = (UInt32*)0x40E00054;      // GPIO GAFR0_L Alt Func Reg 0
        public volatile UInt32* GAFR0U_Address = (UInt32*)0x40E00058;      // GPIO GAFR0_U Alt Func Reg 0

        public volatile UInt32* GAFR1L_Address = (UInt32*)0x40E0005C;      // GPIO GAFR1_L Alt Func Reg 1
        public volatile UInt32* GAFR1U_Address = (UInt32*)0x40E00060;      // GPIO GAFR1_L Alt Func Reg 1

        public volatile UInt32* GAFR2L_Address = (UInt32*)0x40E00064;      // GPIO GAFR2_L Alt Func Reg 2
        public volatile UInt32* GAFR2U_Address = (UInt32*)0x40E00068;      // GPIO GAFR2_L Alt Func Reg 2

        public volatile UInt32* GAFR3L_Address = (UInt32*)0x40E0006C;      // GPIO GAFR3_L Alt Func Reg 3
        public volatile UInt32* GAFR3U_Address = (UInt32*)0x40E00070;      // GPIO GAFR3_L Alt Func Reg 3

        public volatile UInt32* GPLR0_Address = (UInt32*)0x40E00000;       // GPIO Pin-Level Register 0
        public volatile UInt32* GPLR1_Address = (UInt32*)0x40E00004;       // GPIO Pin-Level Register 1
        public volatile UInt32* GPLR2_Address = (UInt32*)0x40E00008;       // GPIO Pin-Level Register 2
        public volatile UInt32* GPLR3_Address = (UInt32*)0x40E00100;       // GPIO Pin-Level Register 3


        public bool IoInput0 = false;       // input from gpio24
        public bool IoInput1 = false;       // input from gpio25
        public bool IoInput2 = false;       // input from gpio108
        public bool IoInput3 = false;       // input from gpio93
        public bool IoInput4 = false;       // input from gpio94
        public bool IoInput5 = false;       // input from gpio95

        public bool IoOutputA1 = false;     // output to gpio103
        public bool IoOutputA2 = false;     // output to gpio104
        public bool IoOutputA3 = false;     // output to gpio105
        public bool IoOutputA4 = false;     // output to gpio27

        public bool bRunIoRelayCtrlThread = true;

        /// <summary>
        /// 
        /// </summary>
        public void IoPumpRelayCtrlThreadBody()
        {
            do
            {
                // forever loop, permanently reads 6 input values for the GUI app
                // to read (latched)
                IoReadInputs();
                System.Threading.Thread.Sleep(100);             // ms
            } while (bRunIoRelayCtrlThread);
        } 

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gpionum"></param>
        /// <param name="opvalue"></param>
        public void IoSetOutput(byte gpionum, bool opvalue)
        {
            switch(gpionum)
            {
                case GPIO103:
                    IoOutputA1 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO103);
                    else
                        GPIOClear(GPIO103);
                    break;

                case GPIO104:
                    IoOutputA2 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO104);
                    else
                        GPIOClear(GPIO104);
                    break;

                case GPIO105:
                    IoOutputA3 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO105);
                    else
                        GPIOClear(GPIO105);
                    break;

                case GPIO27:
                    IoOutputA4 = opvalue;
                    if (opvalue)
                        GPIOSet(GPIO27);
                    else
                        GPIOClear(GPIO27);
                    break;     

                default:
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void IoReadInputs()
        {
            // Called from IoPumpRelayCtrlThread
            IoInput0 = GPIORead(GPIO24);
            IoInput1 = GPIORead(GPIO25);
            IoInput2 = GPIORead(GPIO108);
            IoInput3 = GPIORead(GPIO93);
            IoInput4 = GPIORead(GPIO94);
            IoInput5 = GPIORead(GPIO95);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ipnum"></param>
        /// <param name="ipvalue"></param>
        public void IoClearInput(byte ipnum)
        {
            // Called from GUI
            // Clear specified input
            if (ipnum > 5) return;

            switch (ipnum)
            {
                case 0:
                    IoInput0 = false;
                    break;

                case 1:
                    IoInput1 = false;
                    break;

                case 2:
                    IoInput2 = false;
                    break;

                case 3:
                    IoInput3 = false;
                    break;

                case 4:
                    IoInput4 = false;
                    break;

                case 5:
                    IoInput5 = false;
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool GPIOConfig()
        {
            // Configure outputs
            *GPDR3_Address |= (0x1 << 7);       // gpio103 as output0 (A1)
            *GPDR3_Address |= (0x1 << 8);       // gpio104 as output1 (A2)
            *GPDR3_Address |= (0x1 << 9);       // gpio105 as output2 (A3)
            *GPDR0_Address |= (0x1 << 27);      // gpio27  as output3 (A4)

            // Configure inputs
            *GPDR0_Address |= (0x0 << 24);      // gpio24 as input0
            *GPDR0_Address |= (0x0 << 25);      // gpio25 as input1
            *GPDR3_Address |= (0x0 << 12);      // gpio108 as input2
            *GPDR2_Address |= (0x0 << 29);      // gpio93 as input3
            *GPDR2_Address |= (0x0 << 30);      // gpio94 as input4
            *GPDR2_Address |= (0x0 << 31);      // gpio95 as input5

            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIOSet(byte PinNo)
        {
            switch (PinNo)
            {
                case GPIO103:
                    // OutputA1: GPIO103
                    *GPSR3_Address |= (0x1 << 7);
                    break;

                case GPIO104:
                    // OutputA2: GPIO104
                    *GPSR3_Address |= (0x1 << 8);
                    break;

                case GPIO105:
                    // OutputA3: GPIO105
                    *GPSR3_Address |= (0x1 << 9);
                    break;

                case GPIO27:
                    // OutputA4: GPIO27
                    *GPSR0_Address |= (0x1 << 27);
                    break;
                default:
                    break;
            }

            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIOClear(byte PinNo)
        {
            switch (PinNo)
            {
                case GPIO103:
                    // OutputA1: GPIO103
                    *GPCR3_Address |= (0x1 << 7);
                    break;

                case GPIO104:
                    // OutputA2: GPIO104
                    *GPCR3_Address |= (0x1 << 8);
                    break;

                case GPIO105:
                    // OutputA3: GPIO105
                    *GPCR3_Address |= (0x1 << 9);
                    break;

                case GPIO27:
                    // OutputA4: GPIO27
                    *GPCR0_Address |= (0x1 << 27);
                    break;

                default:
                    break;
            }
            return (false); //for now
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PinNo"></param>
        /// <returns></returns>
        private bool GPIORead(byte PinNo)
        {
            bool res = false;

            switch (PinNo)
            {
                case GPIO24:
                    // Input1: GPIO24
                    res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure. Sample pulse from
                        // e.g. AQL will be ~ 600ms long.
                        System.Threading.Thread.Sleep(100);                         // Sleep for 100ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO25:
                    // Input 2: GPIO25
                    res = (*GPLR0_Address | (1 << 25)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 25)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO108:
                    // Input 3: GPIO108
                    res = (*GPLR3_Address | (1 << 12)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR3_Address | (1 << 12)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO93:
                    // Input4: GPIO93
                    res = (*GPLR2_Address | (1 << 29)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO94:
                    // Input5: GPIO94
                    res = (*GPLR2_Address | (1 << 30)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                case GPIO95:
                    // Input6: GPIO95
                    res = (*GPLR2_Address | (1 << 30)) == 0 ? false : true;
                    if (true == res)
                    {   // we read a '1'; debounce the input to be sure.
                        System.Threading.Thread.Sleep(20);                          // Sleep for 20ms
                        res = (*GPLR0_Address | (1 << 24)) == 0 ? false : true;     // Re-read pin
                    }
                    break;

                default:
                    break;
            }

            return (res);
        }
    }
}

1 Ответ

0 голосов
/ 17 января 2011

Как правило, вы не можете просто написать адрес под WinCE, вам нужно сначала сопоставить его. См. MmMapIoSpace . Обратите внимание, что начиная с CE 6.0 доступно только в режиме ядра и в драйверах пользовательского режима. Если вы хотите использовать его в приложении пользовательского режима, вам нужно будет создать драйвер, который отобразит его для вас.

...