Mam trochę problemów z tą platformą a szczególnie z jedną rzeczą która mnie mocno denerwuje - brak jakiegokolwiek wsparcia !!!
Czekam na odpowiedź z Propoxu i wiem że niedługo się doczekam, ale dzisiaj poruszę to na forum.
Mam nadzieję że ktoś rozwiązał problem , który mnie dręczy a mianowicie:
- chciałbym sterować portami z częstotliwością rzędu 200 khz.
Nie interesują mnie rozwiązania z basha bo jest okropnie wolny. A jedynie rozwiązania kompilowane w C++.
Na początek zaczynam od mrugania diodą ale niestety tu zaczynają się schody bo w Linuxie dostęp do fizycznej warstwy jest okropnie ciężki.
Z dołączonych źródeł OpenWrt niewiele można wywnioskować.
kawałek zmiennych z pliku: ledblink.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#define MAP_SIZE 4096UL /* the size of one page of virtual memory */
#define MAP_MASK (MAP_SIZE - 1) /* mask used for the one page of virtual memory */
#define GPIOF_CON 0x56000050 /* physical address of the GPIO F control register */
#define GPIOF_DAT 0x56000054 /* physical address of the GPIO F data register */
Zaznaczyłem złe adresy bo nie wiem do końca jakie określić dla at91
A at91 jest coś w tym stylu:
/*
* System Peripherals (offset from AT91_BASE_SYS)
*/
#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */
#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */
#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */
#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */
Adresy pinów PIO z pliku gpio.h
#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
#define __ASM_ARCH_AT91RM9200_GPIO_H
#include <asm/irq.h>
#define PIN_BASE NR_AIC_IRQS
#define MAX_GPIO_BANKS 5
/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) (i tak do)
#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31)
#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) (i tak do)
#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31)
#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) (i tak do)
#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) (i tak do)
#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31)
#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) (i tak do)
#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31)
#ifndef __ASSEMBLY__
/* setup setup routines, called from board init or driver probe() */
extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
/* callable at any time */
extern int at91_set_gpio_value(unsigned pin, int value);
extern int at91_get_gpio_value(unsigned pin);
/* callable only from core power-management code */
extern void at91_gpio_suspend(void);
extern void at91_gpio_resume(void);
/*-------------------------------------------------------------------------*/
/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should eventually be removed (along with this errno.h inclusion), and the gpio request/free calls should probably be implemented. */
#include <asm/errno.h>
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
}
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
static inline int gpio_get_value(unsigned gpio)
{
return at91_get_gpio_value(gpio);
}
static inline void gpio_set_value(unsigned gpio, int value)
{
at91_set_gpio_value(gpio, value);
}
#include <asm-generic/gpio.h> /* cansleep wrappers */
static inline int gpio_to_irq(unsigned gpio)
{
return gpio;
}
static inline int irq_to_gpio(unsigned irq)
{
return irq;
}
#endif /* __ASSEMBLY__ */
#endif
Rejestry jednego PINu z pliku at91_pio.h
#ifndef AT91_PIO_H
#define AT91_PIO_H
#define PIO_PER 0x00 /* Enable Register */
#define PIO_PDR 0x04 /* Disable Register */
#define PIO_PSR 0x08 /* Status Register */
#define PIO_OER 0x10 /* Output Enable Register */
#define PIO_ODR 0x14 /* Output Disable Register */
#define PIO_OSR 0x18 /* Output Status Register */
#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
#define PIO_SODR 0x30 /* Set Output Data Register */
#define PIO_CODR 0x34 /* Clear Output Data Register */
#define PIO_ODSR 0x38 /* Output Data Status Register */
#define PIO_PDSR 0x3c /* Pin Data Status Register */
#define PIO_IER 0x40 /* Interrupt Enable Register */
#define PIO_IDR 0x44 /* Interrupt Disable Register */
#define PIO_IMR 0x48 /* Interrupt Mask Register */
#define PIO_ISR 0x4c /* Interrupt Status Register */
#define PIO_MDER 0x50 /* Multi-driver Enable Register */
#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
#define PIO_MDSR 0x58 /* Multi-driver Status Register */
#define PIO_PUDR 0x60 /* Pull-up Disable Register */
#define PIO_PUER 0x64 /* Pull-up Enable Register */
#define PIO_PUSR 0x68 /* Pull-up Status Register */
#define PIO_ASR 0x70 /* Peripheral A Select Register */
#define PIO_BSR 0x74 /* Peripheral B Select Register */
#define PIO_ABSR 0x78 /* AB Status Register */
#define PIO_OWER 0xa0 /* Output Write Enable Register */
#define PIO_OWDR 0xa4 /* Output Write Disable Register */
#define PIO_OWSR 0xa8 /* Output Write Status Register */
Jeszcze jedna dana do zrozumienia PIO
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
#include <asm/io.h>
#include <asm/arch/at91_aic.h>
#define NR_AIC_IRQS 32
/*
* Acknowledge interrupt with AIC after interrupt has been handled.
* (by kernel/irq.c)
*/
#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0)
/*
* IRQ interrupt symbols are the AT91xxx_ID_* symbols
* for IRQs handled directly through the AIC, or else the AT91_PIN_*
* symbols in gpio.h for ones handled indirectly as GPIOs.
* We make provision for 5 banks of GPIO.
*/
#define NR_IRQS (NR_AIC_IRQS + (5 * 32))
/* FIQ is AIC source 0. */
#define FIQ_START AT91_ID_FIQ
#endif
Podałem dość wyczerpującą dokumentację by nawet napisać w asemblerze procedurę odczytu czy zapisu do portu. Ale nie wiem jak mam to ugryść. Potrzebuję więc pomocy.
Poniżej podaję link z rozwiązaniem kogoś kto sobie zaczął mrugać
http://www.tincantools.com/assets/Ledblink.c
Dodam że ledblink.c kompiluje mi się bez zarzutu ale niestety nie działa na MMnet1002 po zmianie adresów ze źródeł powyżej.
Czekam na odpowiedź z Propoxu i wiem że niedługo się doczekam, ale dzisiaj poruszę to na forum.
Mam nadzieję że ktoś rozwiązał problem , który mnie dręczy a mianowicie:
- chciałbym sterować portami z częstotliwością rzędu 200 khz.
Nie interesują mnie rozwiązania z basha bo jest okropnie wolny. A jedynie rozwiązania kompilowane w C++.
Na początek zaczynam od mrugania diodą ale niestety tu zaczynają się schody bo w Linuxie dostęp do fizycznej warstwy jest okropnie ciężki.
Z dołączonych źródeł OpenWrt niewiele można wywnioskować.
kawałek zmiennych z pliku: ledblink.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#define MAP_SIZE 4096UL /* the size of one page of virtual memory */
#define MAP_MASK (MAP_SIZE - 1) /* mask used for the one page of virtual memory */
#define GPIOF_CON 0x56000050 /* physical address of the GPIO F control register */
#define GPIOF_DAT 0x56000054 /* physical address of the GPIO F data register */
Zaznaczyłem złe adresy bo nie wiem do końca jakie określić dla at91
A at91 jest coś w tym stylu:
/*
* System Peripherals (offset from AT91_BASE_SYS)
*/
#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */
#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */
#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */
#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */
Adresy pinów PIO z pliku gpio.h
#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
#define __ASM_ARCH_AT91RM9200_GPIO_H
#include <asm/irq.h>
#define PIN_BASE NR_AIC_IRQS
#define MAX_GPIO_BANKS 5
/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) (i tak do)
#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31)
#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) (i tak do)
#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31)
#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) (i tak do)
#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) (i tak do)
#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31)
#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) (i tak do)
#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31)
#ifndef __ASSEMBLY__
/* setup setup routines, called from board init or driver probe() */
extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
/* callable at any time */
extern int at91_set_gpio_value(unsigned pin, int value);
extern int at91_get_gpio_value(unsigned pin);
/* callable only from core power-management code */
extern void at91_gpio_suspend(void);
extern void at91_gpio_resume(void);
/*-------------------------------------------------------------------------*/
/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should eventually be removed (along with this errno.h inclusion), and the gpio request/free calls should probably be implemented. */
#include <asm/errno.h>
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
}
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
static inline int gpio_get_value(unsigned gpio)
{
return at91_get_gpio_value(gpio);
}
static inline void gpio_set_value(unsigned gpio, int value)
{
at91_set_gpio_value(gpio, value);
}
#include <asm-generic/gpio.h> /* cansleep wrappers */
static inline int gpio_to_irq(unsigned gpio)
{
return gpio;
}
static inline int irq_to_gpio(unsigned irq)
{
return irq;
}
#endif /* __ASSEMBLY__ */
#endif
Rejestry jednego PINu z pliku at91_pio.h
#ifndef AT91_PIO_H
#define AT91_PIO_H
#define PIO_PER 0x00 /* Enable Register */
#define PIO_PDR 0x04 /* Disable Register */
#define PIO_PSR 0x08 /* Status Register */
#define PIO_OER 0x10 /* Output Enable Register */
#define PIO_ODR 0x14 /* Output Disable Register */
#define PIO_OSR 0x18 /* Output Status Register */
#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
#define PIO_SODR 0x30 /* Set Output Data Register */
#define PIO_CODR 0x34 /* Clear Output Data Register */
#define PIO_ODSR 0x38 /* Output Data Status Register */
#define PIO_PDSR 0x3c /* Pin Data Status Register */
#define PIO_IER 0x40 /* Interrupt Enable Register */
#define PIO_IDR 0x44 /* Interrupt Disable Register */
#define PIO_IMR 0x48 /* Interrupt Mask Register */
#define PIO_ISR 0x4c /* Interrupt Status Register */
#define PIO_MDER 0x50 /* Multi-driver Enable Register */
#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
#define PIO_MDSR 0x58 /* Multi-driver Status Register */
#define PIO_PUDR 0x60 /* Pull-up Disable Register */
#define PIO_PUER 0x64 /* Pull-up Enable Register */
#define PIO_PUSR 0x68 /* Pull-up Status Register */
#define PIO_ASR 0x70 /* Peripheral A Select Register */
#define PIO_BSR 0x74 /* Peripheral B Select Register */
#define PIO_ABSR 0x78 /* AB Status Register */
#define PIO_OWER 0xa0 /* Output Write Enable Register */
#define PIO_OWDR 0xa4 /* Output Write Disable Register */
#define PIO_OWSR 0xa8 /* Output Write Status Register */
Jeszcze jedna dana do zrozumienia PIO
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H
#include <asm/io.h>
#include <asm/arch/at91_aic.h>
#define NR_AIC_IRQS 32
/*
* Acknowledge interrupt with AIC after interrupt has been handled.
* (by kernel/irq.c)
*/
#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0)
/*
* IRQ interrupt symbols are the AT91xxx_ID_* symbols
* for IRQs handled directly through the AIC, or else the AT91_PIN_*
* symbols in gpio.h for ones handled indirectly as GPIOs.
* We make provision for 5 banks of GPIO.
*/
#define NR_IRQS (NR_AIC_IRQS + (5 * 32))
/* FIQ is AIC source 0. */
#define FIQ_START AT91_ID_FIQ
#endif
Podałem dość wyczerpującą dokumentację by nawet napisać w asemblerze procedurę odczytu czy zapisu do portu. Ale nie wiem jak mam to ugryść. Potrzebuję więc pomocy.
Poniżej podaję link z rozwiązaniem kogoś kto sobie zaczął mrugać
http://www.tincantools.com/assets/Ledblink.c
Dodam że ledblink.c kompiluje mi się bez zarzutu ale niestety nie działa na MMnet1002 po zmianie adresów ze źródeł powyżej.