Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: arduino/ArduinoCore-zephyr
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a2aa7102302e3283f464d2514889a821e72eab56
Choose a base ref
..
head repository: arduino/ArduinoCore-zephyr
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0cba7ddf5868b69fab798d7245e96a79f807a4f1
Choose a head ref
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ jobs:
west build -p -b beagleconnect_freedom samples/analog_input
- name: Archive firmware
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: firmware
path: Arduino-Zephyr-API/build/zephyr/zephyr.*
2 changes: 1 addition & 1 deletion .github/workflows/license_check.yml
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ jobs:
with:
directory-to-scan: 'scan/'
- name: Artifact Upload
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v3
with:
name: scancode
path: ./artifacts
6 changes: 3 additions & 3 deletions cores/arduino/zephyrCommon.cpp
Original file line number Diff line number Diff line change
@@ -271,7 +271,7 @@ void delay(unsigned long ms) { k_sleep(K_MSEC(ms)); }
void delayMicroseconds(unsigned int us) { k_sleep(K_USEC(us)); }

unsigned long micros(void) {
return k_cyc_to_us_floor32(k_cycle_get_32());
return k_cyc_to_us_floor32(k_cycle_get_64());
}

unsigned long millis(void) { return k_uptime_get_32(); }
@@ -282,11 +282,11 @@ void analogWrite(pin_size_t pinNumber, int value)
{
size_t idx = pwm_pin_index(pinNumber);

if (!pwm_is_ready_dt(&arduino_pwm[idx])) {
if (idx >= ARRAY_SIZE(arduino_pwm) ) {
return;
}

if (idx >= ARRAY_SIZE(arduino_pwm) ) {
if (!pwm_is_ready_dt(&arduino_pwm[idx])) {
return;
}

Binary file modified firmwares/zephyr-arduino_giga_r1_m7.bin
Binary file not shown.
Binary file modified firmwares/zephyr-arduino_giga_r1_m7.elf
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
How to interact with external SDRAM on Portenta H7
The board comes with an hefty 8MB of external fast RAM, which can be used:
- as a framebuffer (raw mode)
- as an expansion of on-chip RAM to store "standard" data
This example shows both the usages
*/

#include "SDRAM.h"

void nonFrameBuffer() {
// Initilize SDRAM for non-framebuffer operations
SDRAM.begin(); // is the same as SDRAM.begin(SDRAM_START_ADDRESS);

// Now we can malloc() and free() in the whole RAM space
// For example, let's create a 7MB array
uint8_t* myVeryBigArray = (uint8_t*)SDRAM.malloc(7 * 1024 * 1024);

// and a small one
uint8_t* mySmallArray = (uint8_t*)SDRAM.malloc(128);

// and use then as usual
for (int i = 0; i<128; i++) {
myVeryBigArray[i] = i;
mySmallArray[i] = i*2;
}

// free the memory when you don't need them anymore
SDRAM.free(myVeryBigArray);
}

void frameBuffer() {
// In case we want a framebuffer-like area at the beginning of the flash,
// simply initialize the memory as

SDRAM.begin(SDRAM_START_ADDRESS + 2 * 1024 * 1024);
// 2MB of contiguous memory available at the beginning

uint32_t* framebuffer = (uint32_t*)SDRAM_START_ADDRESS;

// We can't allocate anymore the huge 7MB array

uint8_t* myVeryBigArray = (uint8_t*)SDRAM.malloc(7 * 1024 * 1024);
if (myVeryBigArray == NULL) {
Serial.println("Oops, too big :)");
}

}

void setup() {
Serial.begin(115200);
while (!Serial);

frameBuffer();
// Uncomment to test the other functionality
// nonFrameBuffer();

// Sort of memtest for stability, useful for testing when overclocking
if (SDRAM.test()) {
Serial.println("SDRAM completely functional");
}
}

void loop() {

}
9 changes: 9 additions & 0 deletions libraries/Zephyr_SDRAM/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=Portenta_SDRAM
version=1.0
author=Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Interact with external SDRAM chip on Portenta H7
paragraph=
category=Other
url=https://github.com/arduino/ArduinoCore-mbed/tree/master/libraries/Portenta_SDRAM
architectures=*
69 changes: 69 additions & 0 deletions libraries/Zephyr_SDRAM/src/SDRAM.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "SDRAM.h"
#include "Arduino.h"

int SDRAMClass::begin(uint32_t start_address) {
if (start_address) {
malloc_addblock((void*)start_address, SDRAM_END_ADDRESS - start_address);
}

return 1;
}

void* SDRAMClass::malloc(size_t size) {
return ea_malloc(size);
}

void SDRAMClass::free(void* ptr) {
ea_free(ptr);
}

bool SDRAMClass::test(bool fast, Stream& _serial) {
uint8_t const pattern = 0xaa;
uint8_t const antipattern = 0x55;
uint8_t *const mem_base = (uint8_t*)SDRAM_START_ADDRESS;

/* test data bus */
for (uint8_t i = 1; i; i <<= 1) {
*mem_base = i;
if (*mem_base != i) {
_serial.println("data bus lines test failed! data (" + String(i) + ")");
__asm__ volatile ("BKPT");
}
}

/* test address bus */
/* Check individual address lines */
for (uint32_t i = 1; i < HW_SDRAM_SIZE; i <<= 1) {
mem_base[i] = pattern;
if (mem_base[i] != pattern) {
_serial.println("address bus lines test failed! address ("+ String((uint32_t)&mem_base[i], HEX) + ")");
__asm__ volatile ("BKPT");
}
}

/* Check for aliasing (overlaping addresses) */
mem_base[0] = antipattern;
for (uint32_t i = 1; i < HW_SDRAM_SIZE; i <<= 1) {
if (mem_base[i] != pattern) {
_serial.println("address bus overlap! address ("+ String((uint32_t)&mem_base[i], HEX) + ")");
__asm__ volatile ("BKPT");
}
}

/* test all ram cells */
if (!fast) {
for (uint32_t i = 0; i < HW_SDRAM_SIZE; ++i) {
mem_base[i] = pattern;
if (mem_base[i] != pattern) {
_serial.println("address bus test failed! address ("+ String((uint32_t)&mem_base[i], HEX) + ")");
__asm__ volatile ("BKPT");
}
}
} else {
memset(mem_base, pattern, HW_SDRAM_SIZE);
}

return true;
}

SDRAMClass SDRAM;
27 changes: 27 additions & 0 deletions libraries/Zephyr_SDRAM/src/SDRAM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef __SDRAM_H
#define __SDRAM_H

#include "ea_malloc.h"

#ifdef __cplusplus

#include "Arduino.h"

#define SDRAM_END_ADDRESS (0xc0800000)
#define SDRAM_START_ADDRESS (0xc0000000)
#define HW_SDRAM_SIZE (8 * 1024 * 1024)

class SDRAMClass {
public:
SDRAMClass() {}
int begin(uint32_t start_address = SDRAM_START_ADDRESS);
void* malloc(size_t size);
void free(void* ptr);
bool test(bool fast = false, Stream& _serial = Serial);
private:

};
extern SDRAMClass SDRAM;

#endif
#endif // __SDRAM_H
46 changes: 46 additions & 0 deletions libraries/ea_malloc/ea_malloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright © 2017 Embedded Artistry LLC.
* License: MIT. See LICENSE file for details.
*/

#ifndef MALLOC_H_
#define MALLOC_H_

#ifdef __cplusplus
extern "C" {
#endif //__cplusplus

#include <stdlib.h>

/**
* @brief Assign blocks of memory for use by malloc().
*
* Initializes the malloc() backend with a memory address and memory pool size.
* This memory is assumed to be owned by malloc() and is vended out when memory is requested.
* Multiple blocks can be added.
*
* NOTE: This API must be called before malloc() can be used. If you call malloc() before
* allocating memory, malloc() will return NULL because there is no available memory
* to provide to the user.
*
* @param addr Pointer to the memory block address that you are providing to malloc()
* @param size Size of the memory block that you are providing to malloc()
*/
void malloc_addblock(void* addr, size_t size);

/**
* @brief Initialize Malloc
*
* Weakly linked, can be overridden based on your needs.
* Each malloc implementation contains a different set of initialization requirements
*/
void malloc_init(void);

void* ea_malloc(size_t size);
void ea_free(void* ptr);

#ifdef __cplusplus
}
#endif //__cplusplus

#endif //MALLOC_H_
Loading