Микроконтроллеры

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Микроконтроллеры » RA » nrf51822


nrf51822

Сообщений 1 страница 30 из 58

1

Целый день потратил на раскуривание классического ПИНАП. И ура! получилось. Зажег светик!
:D и всего - навсего ушел час на прошивку BLE стека. :) (st-link vs keil) К которой у меня в принципе доступа не должно быть. Ибо не покупал не каких плат производителя. Но дальше прошивки стека дело не пошло. Х.З. как им пользоваться.
Перестарались производители со своими многоуровневыми библиотеками, хреновой тучи версий библиотек, примеров и прочей шняги. А простейшего примера примера доступа к регистрам НЕТ! 
Есть ли желающие присоединиться к разбору этого камня на низком уровне, на уровне регистров?
Что я хочу получить от сего камня:
Передача по RADIO одного байта от одного модуля к другому. По примеру nrf24l01, без стека BLE.
Может есть люди кто уже с ним работал? Что-то подскажите?
http://sg.uploads.ru/t/1QKWL.png
Есть масса статей на хабре, но там все вокруг стека и библиотек... А это грустно и не интересно.

Код:
int main(void)
{
    nrf_gpio_cfg_output(21);//пин на выход
    nrf_gpio_pin_set(21);//единицу на пин
	nrf_gpio_pin_clear(21);// ноль на пин, можно через "тумблер"
//nrf_gpio_pin_toggle(21);
	while(1);
}

Знает ли кто нибудь - есть ли в природе хидер с регистрами для камня? Через смещение по базовому адресу, для группы регистров, очень не привычно разбирать камушек. В отладке вижу все регистры, а хидера для обращения к регистрам нэту. Хотя можно и так... Но не удобно. Дефайнить всю карту регистров - гемор.
Разобрался - nrf51.h и есть нужный хидер. А вот битовые поля в соответственно в nrf51bitfields.h.
Вроде удобна запись вида

Код:
nrf_gpio_cfg_output(21);//пин на выход

нежели

Код:
NRF_GPIO->OUTSET|=0x200000;

но где взять все остальные хидеры использования для остальных регистров ( для гпио это nrf_gpio.h) для юзания по этому типу пока не вкурил. В примерах они есть, но все по-отдельности, а нодо все и сразу  :D .
и как всегда туплю

Код:
NRF_GPIO->OUTSET = GPIO_OUTSET_PIN21_Msk ;

равно

Код:
 nrf_gpio_pin_set(21);

ну вот теперь можно дружить с нрф-кой. :whistle:

Код:
int main(void)
{
	NRF_GPIO->DIRSET = GPIO_DIRSET_PIN21_Msk;
	NRF_GPIO->OUTSET = GPIO_OUTSET_PIN21_Msk ;
	while(1);
}

теперь надо собрать проектик с нуля. без всяких паков и ексемплов, насколько это возможно.

2

А что такого сложного?
У меня NRF52832. Проект бареметалл создается весьма просто и в кайло и в SES.
Ну и ссылки , пробуй должно сработать

http://arduino.ru/forum/apparatnye-vopr … e-nrf52832
https://github.com/andenore/NordicSnippets

3

UartE

Код:
#include <nrf.h>
#include <stdio.h>
#define PIN_TXD        (6)
#define PIN_RXD        (8)




    static volatile uint32_t TimingDelay;
	  static volatile uint32_t TimerCntDN;
    static volatile uint32_t TimeOut;




    void SysTick_Handler(void) {
    	
    	static uint8_t  cntdiskio=0;
    	if (TimingDelay) {
        TimingDelay--;
    	}
    	if (TimerCntDN) {
        TimerCntDN--;
    	}
    	if (TimeOut) {
        TimeOut--;
    	}
    	
    	if ( cntdiskio++ >= 10 ) {
       cntdiskio = 0;
	
	
    	}
    }

    
    void Delay_mS(uint32_t nTime) {
    	TimingDelay = nTime;

    	while (TimingDelay);
    }


void UartE_send(char * buf, uint8_t len)
{
	
	NRF_UARTE0->TXD.MAXCNT = len;
  NRF_UARTE0->TXD.PTR = (uint32_t)buf;
  NRF_UARTE0->TASKS_STARTTX = 1;
	while (NRF_UARTE0->EVENTS_ENDTX == 0)
  {
  }
	
}


int main(void)
{
  char buf[32] = {0};
	uint8_t len;
	uint16_t count,count2=0;
  
  // Configure the UARTE with no flow control, one parity bit and 115200 baud rate

  NRF_UARTE0->CONFIG = (UART_CONFIG_HWFC_Disabled   << UART_CONFIG_HWFC_Pos); 
  NRF_UARTE0->BAUDRATE = UARTE_BAUDRATE_BAUDRATE_Baud115200 << UARTE_BAUDRATE_BAUDRATE_Pos;
  
  // Select TX and RX pins
  NRF_UARTE0->PSEL.TXD = PIN_TXD;
  NRF_UARTE0->PSEL.RXD = PIN_RXD;
  
  // Enable the UART (starts using the TX/RX pins)
  NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos;
  
  // Configure transmit buffer and start the transfer
  NRF_UARTE0->TXD.MAXCNT = sizeof(buf);
  NRF_UARTE0->TXD.PTR = (uint32_t)buf;
  NRF_UARTE0->TASKS_STARTTX = 1;
  
  // Wait until the transfer is complete
  while (NRF_UARTE0->EVENTS_ENDTX == 0)
  {
  }
  SysTick_Config(SystemCoreClock /1000);
	Delay_mS(100);	 
	

  
	len=sprintf(buf,"Hello world\n\r");
	
	count=0;
	count2=0;
	
  while (1)
  {
    
    Delay_mS(1000);	
    
    len=sprintf(buf,"RF (%04X / %04X)\n\r",count++,count2--);
    UartE_send(buf,len);
  }
}

4

Передача по RADIO одного байта от одного модуля к другому. По примеру nrf24l01, без стека BLE.


Здесь a5021 уже все сделал http://arduino.ru/forum/apparatnye-vopr … ent-365608
Аурдунья выкашивается на раз-два...

5

dosikus написал(а):

Здесь a5021 уже все сделал http://arduino.ru/forum/apparatnye-vopr … ent-365608
Аурдунья выкашивается на раз-два...

Бегло просмотрел, то что надо. Спасибо. Ушел в себя - разбираться.  :x

6

Создаем проект, выбираем нужный проц, к проекту цепляю только CMSIS и startup.
http://s5.uploads.ru/t/kUW8l.png
дальше создаем файл.c c "кодом"

Код:
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
int main(void)
{
	NRF_GPIO->DIRSET = GPIO_DIRSET_PIN21_Msk;
	NRF_GPIO->OUTSET = GPIO_OUTSET_PIN21_Msk ;
	while(1);
}

Частота 16 МГц, RC oscillator.
http://s5.uploads.ru/t/0RGAl.png
http://sh.uploads.ru/t/vMRTW.png
дальше бум переключаться на кварц.

7

Код:
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
int main(void)
{
  if (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
  NRF_CLOCK->TASKS_HFCLKSTART    = 1;
  while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
  }// теперь на кварце
	NRF_GPIO->DIRSET = GPIO_DIRSET_PIN21_Msk;
	NRF_GPIO->OUTSET = GPIO_OUTSET_PIN21_Msk ;
	while(1);
}

http://sh.uploads.ru/t/iTw08.png
Спасибо dosikus за ссылки дело пошло по-бодрее.

8

Что-то мне не удается системный таймер запустить. dosikus в твоем примере уарта он работает? думаю что - да, а какие настройки в систем инит?
Если быть точнее, то

Код:
SysTick->CTRL  =  SysTick_CTRL_ENABLE_Msk;

ничего не меняет в регистре.
Не активен системный таймер.
http://s9.uploads.ru/t/00os9.png

9

RA, а он точно есть в NRF51?

10

dosikus написал(а):

RA, а он точно есть в NRF51?

:dontknow:  дык вроде должен быть, в составе ядра кортекс м0. Или не обязательно? направление понял, изучу.
Нету его там. Ответ производителя "Unfortunately for you, we've chosed to not implement a SysTick timer in the nRF51822. This is an optional feature in Cortex-M0, and since we believe that all use cases are covered by the other timers, we chose to not implement a separate SysTick timer.
If you need a high-frequency timer, you should be able to use one of the normal timers for that, while if you need a low-power solution, you should look into the RTC timers."

11

RA, не расстраивайся в NRF52 нордик так же не рекомендует юзать систик, говорит что в отличии от RTC систик в спячке блочиться.
Я приткнул систик лишь для быстрого переноса своих наработок при изучении периферии...

12

dosikus написал(а):

RA, не расстраивайся в NRF52 нордик так же не рекомендует юзать систик, говорит что в отличии от RTC систик в спячке блочиться.
Я приткнул систик лишь для быстрого переноса своих наработок при изучении периферии...

дануна, чего там там расстраиваться. нету так нету. другие таймеры никто не отменял. просто с системный быстрее запускается(в смысле осваивается), чтоб помигать светиком это вАще не критично.

13

В ближайшее время планирую вплотную заняться NRF52. RoadMap практически твой- bare_metall , связь с несколькими NRF24 , ну изучение периферии.

14

dosikus написал(а):

В ближайшее время планирую вплотную заняться NRF52. RoadMap практически твой- bare_metall , связь с несколькими NRF24 , ну изучение периферии.

буду ожидать... ты куда-та пристроился к авто индустрии?

15

позволю себе процитировать а5021
"Дошла очередь до таймеров. Их у nRF52832 пять. Таймеры весьма специфичные, если их сравнивать с AVR/PIC/STM32/MSP430. Первое, что бросается в глаза -- это отсутствие прямого доступа к счетчику. Счетчик наличествует, но ни считать из него, ни записать в него ничего нельзя. Можно только сбросить в ноль или через захват скопировать текущее значение в регистр захвата, откуда уже, собственно, прочесть. ... Вызывать прерывание по переполнению счетчика таймеры не умеют..." вот те номер...
все намного хуже, таймеры вообще не имеют прерываний.
http://s8.uploads.ru/t/51hVT.png
и только RTC может генерить прерывание.
http://s9.uploads.ru/t/dPSqy.png
как-то это все дико не привычно после таймеров stm8/32/pic.

16

RA написал(а):

буду ожидать... ты куда-та пристроился к авто индустрии?

Да нет. Временно чисто изучение, чисто для себя. Вся фрилансерская деятельность, пока а может и не пока, задвинута в долгий ящик.

17

dosikus написал(а):

Да нет. Временно чисто изучение, чисто для себя. Вся фрилансерская деятельность, пока а может и не пока, задвинута в долгий ящик.

:crazy:  какое то дичайшее совпадение...

18

блинк

Код:
include <stdbool.h>
#include <stdint.h>
#include <nrf51.h>
#include <nrf51_bitfields.h>
#define PIN_GPIO  (21UL)
volatile uint32_t led=0;
void RTC0_IRQHandler(void)
{
//  volatile uint32_t dummy;
  if (NRF_RTC0->EVENTS_COMPARE[0] == 1)
  {
    NRF_RTC0->EVENTS_COMPARE[0] = 0;

    // Increment compare value with 30.5 ms from current time.
    NRF_RTC0->CC[0] = NRF_RTC0->COUNTER + 10000;

    // Read back event register so ensure we have cleared it before exiting IRQ handler.
 //   dummy = NRF_RTC0->EVENTS_COMPARE[0];
    if(led==0){
    NRF_GPIO->OUTSET = (1UL << PIN_GPIO);
    led=1;
    } 
    else{
    NRF_GPIO->OUTCLR = (1UL << PIN_GPIO);
    led=0;
    }
  }
}
int main(void)
{
	if(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {// если кварц не запущен
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
	}
	NRF_GPIO->PIN_CNF[PIN_GPIO] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
                                (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
  // Start LFCLK (32kHz) crystal oscillator. If you don't have crystal on your board, choose RCOSC instead.
  NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos;
  NRF_CLOCK->TASKS_LFCLKSTART = 1;
  while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
  NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
  // 32kHz timer period
  NRF_RTC0->PRESCALER = 0;
  //  30.5ms us compare value, generates EVENTS_COMPARE[0]
  NRF_RTC0->CC[0] = 10000;
  // Enable EVENTS_COMPARE[0] generation
  NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Enabled << RTC_EVTENSET_COMPARE0_Pos;
  // Enable IRQ on EVENTS_COMPARE[0]
  NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Enabled << RTC_INTENSET_COMPARE0_Pos;
  // Enable RTC IRQ and start the RTC
  NVIC_EnableIRQ(RTC0_IRQn);
  NRF_RTC0->TASKS_START = 1;
	while(1);
}

19

RA написал(а):

все намного хуже, таймеры вообще не имеют прерываний.


Это у NRF51? У NRF52 есть прерывания по compare .

20

dosikus написал(а):

Это у NRF51? У NRF52 есть прерывания по compare .

да это конкретно о nrf51822 , о других не знаю. глянул доку nrf52823, да, отличия есть, и в таймерах, и в радио, в лучшую сторону.
насвистел,  :blush:  сорри. есть "прерывания по compare".

21

вот не бывает идеального продукта, если бы на стм32ф103 добавить радио было бы близко. а так начинаю понимать о чем пытался достучаться vt говоря о простоте и удобстве распределенных систем. по факту - вместо нрф-ного псока, гораздо удобней любой чип с нормальными таймерами + nrf24l01. но так как я упертый баран, простых путей не ищу. ибо не производство, а саморазвитие. на истину не претендую, она у каждого своя.

22

У NRF весьма прикольные что сама периферия что описание ее.
Представление модулей в виде черных ящиков с
унифицированными органами контроля.
Прямо таки напрашивается визуальная тыкалка конфигуратор. :)))))))

23

прием по радио. без передающего.http://sh.uploads.ru/t/zEbLi.png:writing:

24

В смысле шум эфира?
А интересно на нем сниффер/сканер получится?

25

dosikus написал(а):

В смысле шум эфира?
А интересно на нем сниффер/сканер получится?

да ну, это скорее всего кривизна кода... хотя если crc откинуть( не разобрался еще до конца в принципах работы, нет еще четкого понимания, пока тыкаю пальцем в небо) и принимать все что принимается, без адресов бызы и прочего, то может и получится.

26

Tx

Код:
#include <stdbool.h>
#include <stdint.h>
#include <nrf51.h>
#include <nrf51_bitfields.h>

#define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
#define PACKET_STATIC_LENGTH        (1UL)                   //!< Packet static length in bytes
#define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes

#define PIN_GPIO  (21UL)

#define PACKET_S1_FIELD_SIZE      (0UL)  /**< Packet S1 field size in bits. */
#define PACKET_S0_FIELD_SIZE      (0UL)  /**< Packet S0 field size in bits. */
#define PACKET_LENGTH_FIELD_SIZE  (0UL)  /**< Packet length field size in bits. */

static uint32_t swap_bits(uint32_t inp);
static uint32_t bytewise_bitswap(uint32_t inp);
static uint32_t                   packet = 10; 

static uint32_t swap_bits(uint32_t inp)
{
    uint32_t i;
    uint32_t retval = 0;
    
    inp = (inp & 0x000000FFUL);
    
    for (i = 0; i < 8; i++)
    {
        retval |= ((inp >> i) & 0x01) << (7 - i);     
    }
    
    return retval;    
}

static uint32_t bytewise_bitswap(uint32_t inp)
{
      return (swap_bits(inp >> 24) << 24)
           | (swap_bits(inp >> 16) << 16)
           | (swap_bits(inp >> 8) << 8)
           | (swap_bits(inp));
}

void clock_initialization()
{
    /* Start 16 MHz crystal oscillator */
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART    = 1;

    /* Wait for the external oscillator to start up */
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
        // Do nothing.
    }

    /* Start low frequency crystal oscillator for app_timer(used by bsp)*/
    NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_LFCLKSTART    = 1;

    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        // Do nothing.
    }
}
void radio_configure()
{
    // Radio config
    NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
    NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
    NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);

    // Radio address config
    NRF_RADIO->PREFIX0 = 
        ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
      | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
      | ((uint32_t)swap_bits(0xC1) << 8)  // Prefix byte of address 1 converted to nRF24L series format
      | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
  
    NRF_RADIO->PREFIX1 = 
        ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
      | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
      | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format

    NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL);  // Base address for prefix 0 converted to nRF24L series format
    NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL);  // Base address for prefix 1-7 converted to nRF24L series format
  
    NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
    NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive

    // Packet configuration
    NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE     << RADIO_PCNF0_S1LEN_Pos) |
                       (PACKET_S0_FIELD_SIZE     << RADIO_PCNF0_S0LEN_Pos) |
                       (PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"

    // Packet configuration
    NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
                       (RADIO_PCNF1_ENDIAN_Big       << RADIO_PCNF1_ENDIAN_Pos)  |
                       (PACKET_BASE_ADDRESS_LENGTH   << RADIO_PCNF1_BALEN_Pos)   |
                       (PACKET_STATIC_LENGTH         << RADIO_PCNF1_STATLEN_Pos) |
                       (PACKET_PAYLOAD_MAXSIZE       << RADIO_PCNF1_MAXLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"

    // CRC Config
    NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
    if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos))
    {
        NRF_RADIO->CRCINIT = 0xFFFFUL;   // Initial value      
        NRF_RADIO->CRCPOLY = 0x11021UL;  // CRC poly: x^16+x^12^x^5+1
    }
    else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos))
    {
        NRF_RADIO->CRCINIT = 0xFFUL;   // Initial value
        NRF_RADIO->CRCPOLY = 0x107UL;  // CRC poly: x^8+x^2^x^1+1
    }
}

void send_packet()
{
    NRF_RADIO->PACKETPTR = (uint32_t)&packet;
	
    // send the packet:
    NRF_RADIO->EVENTS_READY = 0U;
    NRF_RADIO->TASKS_TXEN   = 1;

    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
    NRF_RADIO->EVENTS_END  = 0U;
    NRF_RADIO->TASKS_START = 1U;

    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }

    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
}

int main(void)
{
	NRF_GPIO->PIN_CNF[PIN_GPIO] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
                                (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
	clock_initialization();
	radio_configure();
  while (1)
  {
    NRF_GPIO->OUTCLR = (1UL << PIN_GPIO);
    send_packet();
    NRF_GPIO->OUTSET = (1UL << PIN_GPIO);
  }
}

27

52 более интересные конечно, жду пока у нас появяться, вроде как к середине октября должны быть.

28

29

TWIM0 работает , перетащил ssd1306 ...

30

Эх, времени мало. Ковыряю PWM на предмет воспроизведения звука +SPI с карточки...

Кстати хорошая штука PPI и GPIOE в связке например с таймером  можно дергать лапкой без прерываний.


Вы здесь » Микроконтроллеры » RA » nrf51822