I am trying to change my pinmuxing modes by device tree overlays, but it seems that it has no effect to the specific registers. I tried the following tutorial:
http://www.valvers.com/embedded-linux/beaglebone-black/step04-gpio/
Default situation:
I am using Debian Linux, image date: 2016-01-24
kernel version: 4.1.15-ti-rt-r43
# output filtered for desired pins:
cat /sys/kernel/debug/pinctrl/44e10800.pinmux/Pins
pin 84 (44e10950.0) 00000037 pinctrl-single
pin 85 (44e10954.0) 00000037 pinctrl-single
pin 86 (44e10958.0) 00000037 pinctrl-single
pin 87 (44e1095c.0) 00000037 pinctrl-single
As you can see the all have mode 7, I need mode 0 (SPI0).
And no one else is using the pin (pretty much the same on every pin => GPIO UNCLAIMED):
pin 84 (44e10950.0): ocp:P9_22_pinmux (GPIO UNCLAIMED) function pinmux_P9_22_default_pin group pinmux_P9_22_default_pin
cat /sys/devices/platform/bone_capemgr/slots
0: PF---- -1
1: PF---- -1
2: PF---- -1
3: PF---- -1
4: P-O-L- 0 Override Board Name,00A0,Override Manuf,cape-universaln
Here is my device tree:
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
part-number = "SPI_SLAVE_PINMUX";
version = "00A0";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
spi_slave: pinmux_spi_slave {
pinctrl-single,pins = <
0x150 0x30 // SPI0_CS0 Mode 0, SPI
0x154 0x30 // SPI0_D1 Mode 0, SPI
0x158 0x10 // SPI0_D0 Mode 0, SPI
0x15c 0x10 // SPI0_SCLK Mode 0, SPI
>;
};
};
};
fragment#1 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size.cells = <0>;
compatible = "bone-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&spi_slave>;
status = "okay";
};
};
};
Then I compile my dts file and copy the compiled file to /lib/Firmware.
dtc -O dtb -o SPI_SLAVE_PINMUX-00A0.dtbo -b O -# SPI_SLAVE_PINMUX-00A0.dts
After that I install the driver:
echo SPI_SLAVE_PINMUX > /sys/devices/platform/bone_capemgr/slots
The overlay is loaded:
root#beaglebone:~# cat /sys/devices/platform/bone_capemgr/slots
0: PF---- -1
1: PF---- -1
2: PF---- -1
3: PF---- -1
4: P-O-L- 0 Override Board Name,00A0,Override Manuf,cape-universaln
7: P-O-L- 1 Override Board Name,00A0,Override Manuf,SPI_SLAVE_PINMUX
Now the problem: if I execute the following command:
cat /sys/kernel/debug/pinctrl/44e10800.pinmux/Pins
I can see that nothing has changed.
pin 84 (44e10950.0) 00000037 pinctrl-single
pin 85 (44e10954.0) 00000037 pinctrl-single
pin 86 (44e10958.0) 00000037 pinctrl-single
pin 87 (44e1095c.0) 00000037 pinctrl-single
And I am wondering how this device tree fits to my device driver (char device driver, with access to MCSPI Memory to manipulate registers), but that's a different story... ;)
I would be very grateful, if someone could help me through ...
Many thanks in advance
Related
For a project I try do use the ESP8266 RTOS SDK.
First step I install the tools and the toolchain. The hello_world example and the other gpio example works fine. I try the softAP example and get a Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled Error. I figured out that the line 62 : .automode = WIFI_AUTH_WPA_WPA2_PSK not works. I tried WIFI_AUTH_WEP,WIFI_AUTH_WPA_PSK,WIFI_AUTH_WPA2_PSK but only with WIFI_AUTH_OPEN the softAP works. Anyone same behavior or some tips?
Console Trace:
ets Jan 8 2013,rst cause:1, boot mode:(3,6)
load 0x40100000, len 7040, room 16
tail 0
chksum 0xe5
load 0x3ffe8408, len 24, room 8
tail 0
chksum 0x6c
load 0x3ffe8420, len 3312, room 8
tail 8
chksum 0x75
csum 0x75
I (123) boot: ESP-IDF v3.4-rc 2nd stage bootloader
I (123) boot: compile time 19:41:32
I (207) qio_mode: Enabling default flash chip QIO
I (207) boot: SPI Speed : 40MHz
I (208) boot: SPI Mode : QOUT
I (212) boot: SPI Flash Size : 2MB
I (219) boot: Partition Table:
I (224) boot: ## Label Usage Type ST Offset Length
I (236) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (247) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (259) boot: 2 factory factory app 00 00 00010000 000f0000
I (271) boot: End of partition table
I (277) esp_image: segment 0: paddr=0x00010010 vaddr=0x40210010 size=0x52c80 (339072) map
I (406) esp_image: segment 1: paddr=0x00062c98 vaddr=0x40262c90 size=0x0f594 ( 62868) map
I (428) esp_image: segment 2: paddr=0x00072234 vaddr=0x3ffe8000 size=0x005fc ( 1532) load
I (429) esp_image: segment 3: paddr=0x00072838 vaddr=0x40100000 size=0x00080 ( 128) load
I (439) esp_image: segment 4: paddr=0x000728c0 vaddr=0x40100080 size=0x05560 ( 21856) load
I (460) boot: Loaded app from partition at offset 0x10000
I (481) wifi softAP: ESP_WIFI_MODE_AP
I (484) system_api: Base MAC address is not set, read default base MAC address from EFUSE
I (486) system_api: Base MAC address is not set, read default base MAC address from EFUSE
phy_version: 1163.0, 665d56c, Jun 24 2020, 10:00:08, RTOS new
I (557) phy_init: phy ver: 1163_0
I (567) wifi softAP: ----------------###------------
ESP_ERROR_CHECK failed: esp_err_t 0x2 (ERROR) at 0x4021f7cc
file: "softap_example_main.c" line 73
func: wifi_init_softap
expression: esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config)
abort() was called at PC 0x4021f7cf on core 0
Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x40221c72 PS : 0x00000030 A0 : 0x40221c70 A1 : 0x3ffeb550
A2 : 0x00000000 A3 : 0xffffffdb A4 : 0x00000001 A5 : 0x00000001
A6 : 0x00000000 A7 : 0x4026663c A8 : 0x00000020 A9 : 0x00000000
A10 : 0x00000008 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001e EXCCAUSE: 0x0000001d
Backtrace: 0x40221c72:0x3ffeb550 0x4021f7d2:0x3ffeb560 0x4022182e:0x3ffeb570 0x40221894:0x3ffeb630 0x402118ef:0x3ffeb640
Example Code from GitHub: (examples/wifi/getting_started/softAP/main/softap_example_main.c)
/* WiFi softAP Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
/* The examples use WiFi configuration that you can set via project configuration menu.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_MAX_STA_CONN CONFIG_ESP_MAX_STA_CONN
static const char *TAG = "wifi softAP";
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
MAC2STR(event->mac), event->aid);
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
MAC2STR(event->mac), event->aid);
}
}
void wifi_init_softap()
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
.password = EXAMPLE_ESP_WIFI_PASS,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA_WPA2_PSK
},
};
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
wifi_init_softap();
}
You have to run idf.py menuconfig and set the SSID and password values.
Password´s under 8 characters gets a Guru-Meditation ERR if the
wifi_config.ap.authmode = WIFI_AUTH_WEP or,
wifi_config.ap.authmode = WIFI_AUTH_WPA_PSK or,
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK . Other authmodes not yet testet.
To provid this Error, make sure your pw has more then 7 characters or/and set
the If-Condition after the wifi_config to:
if (strlen(EXAMPLE_ESP_WIFI_PASS) < 8) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
ESP_LOGI(TAG," pw-lenght under 8 charcters. Set WIFI_AUTH_OPEN");
}
Your WiFi is not protectet but your µC not crashes.
I have different raster bands and I need to get a proper image from these bands using OpenCV. How can it be done?
As an alternative to my other answer, you could put a small ASCII header on your raw files to make them into PGM files which OpenCV can read natively without any extra libraries. The PGM format is part of the NetPBM suite described here on Wikipedia.
So, let's say each of your rasters is a single channel, 8-bit image with dimensions 100 px wide by 256 px tall. Make each band into a PGM image in the Terminal:
{ printf "P5\n100 256\n255\n"; cat band1.dat; } > band1.pgm
{ printf "P5\n100 256\n255\n"; cat band2.dat; } > band2.pgm
{ printf "P5\n100 256\n255\n"; cat band3.dat; } > band3.pgm
{ printf "P5\n100 256\n255\n"; cat band4.dat; } > band4.pgm
You now have 4 greyscale images you can view with GIMP or feh and, more importantly which OpenCV can read. So your code becomes:
Mat b1 = imread("band1.pgm", IMREAD_UNCHANGED);
Mat b2 = imread("band2.pgm", IMREAD_UNCHANGED);
Mat b3 = imread("band3.pgm", IMREAD_UNCHANGED);
Mat b4 = imread("band4.pgm", IMREAD_UNCHANGED);
// Now merge
auto channels = std::vector<cv::Mat>{b1, b2, b3, b4};
cv::Mat FourBandBoy;
cv::merge(channels, FourBandBoy);
As you haven't provided any sample raster images, I made 4 images, each 100x256, for a quick demonstration. Here they are:
-rw-r--r-- 1 mark staff 25600 21 Mar 10:44 band1.dat
-rw-r--r-- 1 mark staff 25600 21 Mar 10:44 band2.dat
-rw-r--r-- 1 mark staff 25600 21 Mar 10:44 band3.dat
-rw-r--r-- 1 mark staff 25600 21 Mar 10:44 band4.dat
Hopefully, you can see from the sizes that they are 100x256, single channel and 8-bit.
I the converted them to PGM per the original instructions:
{ printf "P5\n100 256\n255\n"; cat band1.dat; } > band1.pgm
{ printf "P5\n100 256\n255\n"; cat band2.dat; } > band2.pgm
{ printf "P5\n100 256\n255\n"; cat band3.dat; } > band3.pgm
{ printf "P5\n100 256\n255\n"; cat band4.dat; } > band4.pgm
which gives:
-rw-r--r-- 1 mark staff 25615 21 Mar 10:44 band1.pgm
-rw-r--r-- 1 mark staff 25615 21 Mar 10:44 band2.pgm
-rw-r--r-- 1 mark staff 25615 21 Mar 10:44 band3.pgm
-rw-r--r-- 1 mark staff 25615 21 Mar 10:44 band4.pgm
So, you can see the PGM header amounts to 15 bytes. The images look like this now:
I slightly modified the code:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <cstdio>
using namespace cv;
using namespace std;
int
main(int argc,char*argv[])
{
Mat b1 = imread("band1.pgm", IMREAD_UNCHANGED);
Mat b2 = imread("band2.pgm", IMREAD_UNCHANGED);
Mat b3 = imread("band3.pgm", IMREAD_UNCHANGED);
Mat b4 = imread("band4.pgm", IMREAD_UNCHANGED);
// Now merge
auto channels = std::vector<cv::Mat>{b1,b2,b3,b4};
cv::Mat BigBoy;
cv::merge(channels, BigBoy);
// Save
cv::imwrite("result.png",BigBoy);
}
And the result...
Hopefully you can see that the resulting image:
is blue where there was a lot of white in band1,
is green where there was a lot of white in band2,
is red where band3 was white
is transparent where band 4 was black
I don't feel like writing all the code and testing it like I ordinarily might so I'll just give you an outline of one way to do it.
Assume your images are WIDTHxHEIGHT in dimension and made of unsigned char data written consecutively without padding into files called band1.dat, band2.dat etc.
// Step 1: Allocate a buffer: raw = WIDTHxHEIGHT bytes
// Step 2: Load one band from disk into raw buffer
open band1.dat, read WIDTH*HEIGHT bytes into raw, close band1.dat
// Make a single band Mat from that data
cv::Mat band1(HEIGHT,WIDTH,CV_8UC1);
// Copy the raw data into it so we can re-use buffer
std::memcpy(band1.data,raw,WIDTH*HEIGHT);
// Repeat step 2 for bands 2-4 so you have 4 separate, single channel Mats
// Now merge the 4 individual channels into 4-band bad boy
auto channels = std::vector<cv::Mat>{band1, band2, band3, band4};
cv::Mat FourBandBoy;
cv::merge(channels, FourBandBoy);
I need to realise a PWM output with 5 kHz +/- 5%. (Presumably due to a filter circuit into which this feeds over which I have no control.)
Is this realisable with a ESP8266 (ideally with NodeMCU)?
I realise that the software PWM of the ESP8266 has a maximum frequency of 1 kHz while the sigma-delta can be used to implement a PWM with a fixed frequency of about 300 kHz.
So is there a reliable way to achieve 5 kHz? I know some people experimented with the I2S peripheral for waveform output but I am unsure whether it can be used for 5kHz output.
Has anybody looked at into a similar problem before?
The essential code is:
#define qap 2 // Quick As Possible ... Duty cycle only 0, 50, 100%
#define HFreq 5150
#define pPulse D2 // a NodeMCU/ESP8266 GPIO PWM pin
analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1); // start PWM
TL;DR
Just did some crude benchamrks
// had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost
nominally with 80 MHz clock got
// 72.24 KHz 361178 2015061929
// 72.23 KHz 361163 2415062390
// 72.23 KHz 361133 2815062824
and
// 141.52 KHz 353809 2009395076
// 141.54 KHz 353846 2409395627
// 141.52 KHz 353806 2809395946
with 160 MHz clock
CAVEATS!!!
1. The duty cycle range is 2!
2. As well the system had no other conditioning, so other timing artifacts were still present from Serial IO etc. In particular instability due to the WDT and WiFi penultimately appeared. (Anyhow, presumably this is an issue only when the ESP8266 is under stress and duress.)
// 141.50 KHz 353754 619466806
// 141.52 KHz 353810 1019467038
// ...
// ad infinitum cum tempore finitum, infinitus est ad nauseum?
// ...
// 141.54 KHz 353857 735996888
//
// ets Jan 8 2013,rst cause:4, boot mode:(1,7)
//
//wdt reset
When using the following code to generate a 5 KHz square wave signal, the considerations above are not an issue and do not occur.
// ------------ test results for 80 MHz clock --------------
//
//
// PWM pulse test
//
// F_CPU: 80000000L
// ESP8266_CLOCK: 80000000UL
// PWM "freq.": 5150
//
//
// connect D1 to D2
//
//
// raw MPU
// frequency count cycle
// 0.00 KHz 1 407976267
// 4.74 KHz 9482 567976702
// 5.00 KHz 10007 727977137
// 5.00 KHz 10006 887977572
// 5.00 KHz 10006 1047978007
// 5.00 KHz 10007 1207978442
// 5.00 KHz 10006 1367978877
// 5.00 KHz 10006 1527979312
// 5.00 KHz 10007 1687979747
// 5.00 KHz 10006 1847980182
// 5.00 KHz 10006 2007980617
// 5.00 KHz 10007 2167981052
// 5.00 KHz 10006 2327981487
// 5.00 KHz 10006 2487981922
// 5.00 KHz 10007 2647982357 ...
//
// crude testing for 5KHz signal
// extracted from:
// highest frequency / shortest period pin pulse generate / detect test
//
// uses raw ESP8266 / NodeMCU V1.0 hardware primitive interface of Arduino IDE (no included libraries)
//
// timing dependencies: WDT, WiFi, I2S, I2C, one wire, UART, SPI, ...
//
// Arduino GPIO 16 5 4 0 2 14 12 13 15 3 1 0 1 2 3 4 5 ... 12 13 14 15 16
// NodeMCU D pin 0 1 2 3 4 5 6 7 8 9 10 3 10 4 9 2 1 ... 6 7 5 8 0
// | | | | | | | | | | |
// a WAKE | | F Tx1 | | Rx2 Tx2 Rx0 Tx0
// k (NO PWM or | | L blue | | | |
// a' interrupt) | S A * H | H | H | | * led's
// s red S D S S M S H
// * C A H C I I C
// L T L S M S
// K A K O O
// └ - - - - └----UART's----┘
// └--I2C--┘ └-----SPI------┘
//
// rules of engagement are obscure and vague for effects of argument values for the paramters of these functions:
// analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1);
//
// http://stackoverflow.com/questions/42112357/how-to-implement-esp8266-5-khz-pwm
//
// system #defines: F_CPU ESP8266_CLOCK
#define pInt D1 // HWI pin: NOT D0 ie. GPIO16 is not hardwared interrupt or PWM pin
#define pPulse D2 // PWM pulsed frequency source ... ditto D0 (note: D4 = blue LED)
#define countFor 160000000UL
#define gmv(p) #p // get macro value
#define em(p) gmv(p) // evaluate macro
#define qap 2 // minimal number of duty cycle levels (0, 50, 100% ) Quick As Possible ...
#define HFreq 5150 //((long int) F_CPU==80000000L ? 125000 : 250000) // ... to minimize time of a cycle period
// max values ^ and ^ found empirically
// had HFreq=126400 with 75 KHz pulse at 80 MHz ESP clock, every 1 sec but proof of evidence lost
#define infoTxt (String) \
"\n\n\t PWM pulse test " \
"\n F_CPU: " em(F_CPU) \
"\n ESP8266_CLOCK: " em(ESP8266_CLOCK) \
"\n PWM \"freq.\": " + HFreq + "\n" \
"\n\n connect " em(pInt) " to " em(pPulse) "\n" \
"\n\n raw MPU " \
" \n frequency count cycle "
long int oc=1, cntr=1;
unsigned long int tc=0;
void hwISR(){ cntr++; } // can count pulses if pInt <---> to pPulse
void anISR(){ tc=ESP.getCycleCount(); timer0_write( countFor + tc ); oc=cntr; cntr=1; }
void setup() { // need to still confirm duty cycle=50% (scope it or ...)
noInterrupts();
Serial.begin(115200); Serial.println(infoTxt); delay(10); // Serial.flush(); Serial.end(); // Serial timing?
analogWriteRange(qap); analogWriteFreq( HFreq ); analogWrite(pPulse, 1); // start PWM
pinMode( pInt, INPUT ); attachInterrupt(pInt, hwISR, RISING); // count pulses
timer0_isr_init(); timer0_attachInterrupt( anISR ); anISR(); //
interrupts();
}
void loop() { delay(10); if (oc==0) return;
Serial.println((String)" "+(oc/1000.0*F_CPU/countFor)+" KHz "+oc+" "+tc); oc=0; }
//
You can also use the hardware SPI interface which has an adjustable clock speed.
By writing continuous data, the output waveform appears on SCLK.
I've figured out the abovementioned while creating a knight rider effect with IC 74hc595 on ESP8266, using MicroPython (which is indeed slow, as being a script language).
It worked for me up to 4MHz SPI clock speed.
The disadvantage is, for permanent waveform, you need to write data to MOSI forever (as when SPI data buffer goes empty, there is no signal on SCLK anymore).
I have a problem with the RTOS firmware on the esp8266 (I have a esp12e), after flashing the firmware, reading from uart, it keeps stuck with those lines:
ets Jan 8 2013,rst cause:2, boot mode:(3,0)
load 0x40100000, len 31584, room 16
tail 0
chksum 0x24
load 0x3ffe8000, len 944, room 8
tail 8
chksum 0x9e
load 0x3ffe83b0, len 1080, room 0
tail 8
chksum 0x60
csum 0x60
Now I will explain my HW setup:
GPIO15 -> Gnd
EN -> Vcc
GPIO0 -> Gnd (when flashing)
GPIO0 -> Vcc (normal mode)
For the toolchain I've followed this tutorial and it works well:
http://microcontrollerkits.blogspot.it/2015/12/esp8266-eclipse-development.html
Then I started doing my RTOS blink example, I post my user_main.c code here:
#include "esp_common.h"
#include "gpio.h"
void task2(void *pvParameters)
{
printf("Hello, welcome to client!\r\n");
while(1)
{
// Delay and turn on
vTaskDelay (300/portTICK_RATE_MS);
GPIO_OUTPUT_SET (5, 1);
// Delay and LED off
vTaskDelay (300/portTICK_RATE_MS);
GPIO_OUTPUT_SET (5, 0);
}
}
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
uart_init_new();
printf("SDK version:%s\n", system_get_sdk_version());
// Config pin as GPIO5
PIN_FUNC_SELECT (PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
xTaskCreate(task2, "tsk2", 256, NULL, 2, NULL);
}
I also post the flash command, the first executed one time, the second every time I modify the code:
c:/Espressif/utils/ESP8266/esptool.exe -p COM3 write_flash -ff 40m -fm qio -fs 32m 0x3FC000 c:/Espressif/ESP8266_RTOS_SDK/bin/esp_init_data_default.bin 0x3FE000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin 0x7E000 c:/Espressif/ESP8266_RTOS_SDK/bin/blank.bin
c:/Espressif/utils/ESP8266/esptool.exe -p COM3 -b 256000 write_flash -ff 40m -fm qio -fs 32m 0x00000 firmware/eagle.flash.bin 0x40000 firmware/eagle.irom0text.bin
There is something wrong? I really don't understand why it doesn't work.
When I try the NON-OS example they works very well.
I had the same problem as you. This issue is caused by the incorrect address of the eagle.irom0text.bin .
So I changed the address of the eagle.irom0text.bin from 0x40000 (0x10000) to 0x20000 and it worked well for me.
[RTOS SDK version: 1.4.2(f57d61a)]
The correct flash codes in the common_rtos.mk (ESP-12E)
for flashinit
flashinit:
$(vecho) "Flash init data default and blank data."
$(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fc000 $(SDK_BASE)/bin/esp_init_data_default.bin
$(ESPTOOL) -p $(ESPPORT) write_flash $(flashimageoptions) 0x3fe000 $(SDK_BASE)/bin/blank.bin
for flash:
flash: all
#ifeq ($(app), 0)
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin
else
ifeq ($(boot), none)
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) 0x00000 $(FW_BASE)/eagle.flash.bin 0x20000 $(FW_BASE)/eagle.irom0text.bin
else
$(ESPTOOL) -p $(ESPPORT) -b $(ESPBAUD) write_flash $(flashimageoptions) $(addr) $(FW_BASE)/upgrade/$(BIN_NAME).bin
endif
endif
I have troubles with enabling SPI on BBB, ofc followed tutorial from the hipstercircuits.com.
I even installed a fresh arch linux to the uSD in case I really messed up system on eMMC.
My settings are:
Since SPI1 has issues with HDMI I disabled anything HDMI related I found.
Not sure about fdfile entry though, found it somewhere on the web. (I also tried without it)
Currently I'm working on the SD card if that matters.
uEnv.txt
optargs=quiet coherent_pool=1M fdtfile=am335x-boneblack.dtb capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
I took dts file straight from the hipstercircuits.com and compiled it with alarm/dtc-overlay 1.4.1-1 installed via pacman.
After disabling HDMI in uEnv.txt
[root#alarm ~]# echo BB-SPI1-01 > /sys/devices/bone_capemgr.*/slots
went ok and I saw:
[root#alarm ~]# cat /sys/devices/bone_capemgr.9/slots
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-SPI1-01
I also tried echoing BB-SPIDEV0, BB-SPIDEV1 and BB-SPIDEV1A1 found here:
[root#alarm spi_a]# ls -l /lib/firmware | grep SPI
-rw-r--r-- 1 root root 1351 Jan 29 17:04 BB-SPI1-01-00A0.dtbo
-rw-r--r-- 1 root root 1185 Jan 25 01:06 BB-SPIDEV0-00A0.dtbo
-rw-r--r-- 1 root root 1185 Jan 25 01:06 BB-SPIDEV1-00A0.dtbo
-rw-r--r-- 1 root root 1185 Jan 25 01:06 BB-SPIDEV1A1-00A0.dtbo
Result of the spidev_test is always the same.
What is more interesting I didn't see anything about P9_29, P9_31 etc, which are part of SPI1, in pingroups:
[root#alarm ~]# cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pingroups
registered pin groups:
group: pinmux_userled_pins
pin 21 (44e10854)
pin 22 (44e10858)
pin 23 (44e1085c)
pin 24 (44e10860)
group: pinmux_rstctl_pins
pin 20 (44e10850)
group: pinmux_i2c0_pins
pin 98 (44e10988)
pin 99 (44e1098c)
group: pinmux_i2c2_pins
pin 94 (44e10978)
pin 95 (44e1097c)
group: pinmux_mmc1_pins
pin 88 (44e10960)
group: pinmux_emmc2_pins
pin 32 (44e10880)
pin 33 (44e10884)
pin 0 (44e10800)
pin 1 (44e10804)
pin 2 (44e10808)
pin 3 (44e1080c)
pin 4 (44e10810)
pin 5 (44e10814)
pin 6 (44e10818)
pin 7 (44e1081c)
group: pinmux_userled_pins
pin 21 (44e10854)
pin 22 (44e10858)
pin 23 (44e1085c)
pin 24 (44e10860)
The spidevs are present in /dev
[root#alarm ~]# ls -l /dev | grep spi
crw------- 1 root root 153, 1 Jan 29 17:13 spidev1.0
crw------- 1 root root 153, 0 Jan 29 17:13 spidev1.1
To test the interface both python method mentioned in the tutorial and spidev_test.c (spidev_test.c) compiled on the BBB were used.
[root#alarm ~]# gcc spidev_test.c -o spidev_test
In case of python library there is no error but also nothing at the output - not even a clock signal on the SCL line.
spidev_test returns:
[root#alarm spi_a]# ./spidev_test
can't set spi mode: Inappropriate ioctl for device
Aborted (core dumped)
[root#alarm spi_a]# ./spidev_test -D /dev/spidev1.0
can't set spi mode: Inappropriate ioctl for device
Aborted (core dumped)
[root#alarm spi_a]# ./spidev_test -D /dev/spidev1.1
can't set spi mode: Inappropriate ioctl for device
Aborted (core dumped)
Do I have to make use of *.dts and *.dtb files provided at the beginning of the hipstercircuit's tutorial?
I probably screwed up sth easy. Any ideas what was it?
Did you get it working just like that?
All advices are welcome and will be very appreciated! ;)
I used this .dts and worked fine (both spidev1.0 and spidev1.1 on the spidev_test.c). There are some more lines than in the linux documentation which allow to enable second chip select for being used by SPI1 and properly configure the GPIO on the pin 42.
You should see now the spi pin muxing correctly.
/*
* Copyright (C) 2013 CircuitCo
*
* Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "BB-SPI1-01";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P9.31", /* spi1_sclk */
"P9.29", /* spi1_d0 */
"P9.30", /* spi1_d1 */
"P9.28", /* spi1_cs0 */
"P9.42", /* spi1_cs1 */
/* the hardware ip uses */
"spi1";
fragment#0 {
target = <&am33xx_pinmux>;
__overlay__ {
/* default state has all gpios released and mode set to uart1 */
bb_spi1_pins: pinmux_bb_spi1_pins {
pinctrl-single,pins = <
0x190 0x33 /* mcasp0_aclkx.spi1_sclk, INPUT_PULLUP | MODE3 */
0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
0x164 0x12 /* eCAP0_in_PWM0_out.spi1_cs1 OUTPUT_PULLUP | MODE2 */
0x1A0 0x32 /* Other P42 pin, INPUT_PULLUP */
>;
};
};
};
fragment#1 {
target = <&spi1>; /* spi1 is numbered correctly */
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bb_spi1_pins>;
#address-cells = <1>;
#size-cells = <0>;
spi1_0{
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <0>;
spi-max-frequency = <16000000>;
};
spi1_1{
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <1>;
spi-max-frequency = <16000000>;
};
};
};};
I think the problem is the ioctl.h.
When I search for 'iotl.h', the result is as follows,
/usr/include/arm-linux-gnueabihf/sys/ioctl.h
/usr/include/arm-linux-gnueabihf/asm/ioctl.h
/usr/include/linux/ioctl.h
/usr/include/linux/hdlc/ioctl.h
/usr/include/linux/mmc/ioctl.h
/usr/include/asm-generic/ioctl.h
So there is no corresponding sys/ioctl.h
I am trying to find the correct ioctl.h