-
Notifications
You must be signed in to change notification settings - Fork 3k
Add support for ADI EV-COG-AD4050LZ platform. #5144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
retest uvisor |
#elif defined(__ICCARM__) | ||
__root | ||
#endif | ||
const uint32_t SECTION_PLACE(blank_checksum[],".checksum") = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will this work with bootloader?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either the flash image would need to have the checksum blocks defined or the bootloader would need to write these checksum blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @c1728p9
which address 0x20000000. | ||
*----------------------------------------------------------------------------*/ | ||
#ifdef __ICCARM__ | ||
void (*__Relocated___Vectors[NVIC_NUM_VECTORS])(void) @(NVIC_RAM_VECTOR_ADDRESS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this needed as mbed boot handles nvic reallocation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed, will remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in ce580dd
targets/targets.json
Outdated
@@ -109,8 +109,8 @@ | |||
"extra_labels": ["NXP", "LPC11UXX"], | |||
"macros": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], | |||
"supported_toolchains": ["ARM", "uARM", "GCC_ARM"], | |||
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SLEEP", "SPI", "SPISLAVE"], | |||
"default_lib": "small", | |||
"device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SLEEP", "SPI", "SPISLAVE"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bad rebase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the target 'LPC11U34_421', probably modified by the git merge. The changes in target.json for the COG4050 platform should just be localized to the "EV_COG_AD4050LZ" section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix in the next commit.
#define OS_CLOCK 26000000 | ||
#endif | ||
#ifndef MBED_CONF_APP_THREAD_STACK_SIZE | ||
#define MBED_CONF_APP_THREAD_STACK_SIZE 1024 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is app specific config that by default is 4k in mbed, why is this changing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was failing one of the tests because the creation of multiple threads were overflowing the heap, hence the limitation of the thread stack size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe test should be updated , not target. Target should have default one (all targets are equal).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either that or there should be some guidelines on what minimal stack and heap sizes are required for passing all the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either that or there should be some guidelines on what minimal stack and heap sizes are required for passing all the tests.
👍 , can you please for now remote this from a target configuration and move this to the test rather, send a separate patch that we can review?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed from mbed_rtx.h. However I can't remember which test I had problem with, will try to find it.
#define OS_TASKCNT 6 | ||
#endif | ||
#ifndef OS_MAINSTKSIZE | ||
#define OS_MAINSTKSIZE 112 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arent some of these macros from older RTX version? not valid anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't quite sure whether these were still needed since the move to RTX5, will remove.
SPI_Handle = *obj->pSPI_Handle; | ||
SPI_Return = adi_spi_SetMasterMode(SPI_Handle, master); | ||
if (SPI_Return) { | ||
obj->error = SPI_EVENT_ERROR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whats the intention with `obj->error`` ? how is it used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is there to store any error codes from the adi spi driver
#if DEVICE_SERIAL_ASYNCH | ||
uint8_t serial_tx_active(serial_t *obj) | ||
{ | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These async should also not be here, as it's not functional - tests will fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean they should be removed from the source file if not implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is what I was asking. If this is enabled and has no implementation leads to runtime errors that are harder to catch than simple not defined = not implemented?
|
||
void i2c_reset(i2c_t *obj) | ||
{ | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are these empty, even byte write/read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required as adi_i2c_Reset() is called from i2c_init()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case yes, but in case of API, as this is HAL API, a user can create I2C API and this should be implemented.
|
||
/** Analogin hal structure. analogin_s is declared in the target's hal | ||
*/ | ||
typedef struct analogin_s analogin_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this defined already in analogin_api header file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in ce580dd
/* Enable the ADC */ | ||
adi_adc_Enable (hDevice, true); | ||
|
||
adi_adc_GetBuffer (hDevice, &pAdcBuffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adi_adc_GetBuffer (hDevice, &pAdcBuffer);
should not have space between function name and arguments, in lot of lines in thsi file it is like that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in ce580dd
Let us know once you update this codebase |
- Removed unneeded code from i2c and serial modules.
#define TRNG_CNT_VAL 4095 | ||
#define TRNG_PRESCALER 2 | ||
|
||
static ADI_RNG_HANDLE RNGhDevice; /* Memory to handle CRC Device */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not have ADI_RNG_HANDLE
as a member of the trng_t
object, and then the trng_t
will not be unused parameter. (That's the purpose of the trng_t
structure)
// Prescaler: 0 - 10 | ||
// LenReload: 0 - 4095 | ||
#define TRNG_CNT_VAL 4095 | ||
#define TRNG_PRESCALER 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the values of TRNG_CNT_VAL
and TRNG_PRESCALER
defined? What do they mean? Do these values gurantee there will be full entropy from the source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These set the sample length register in the RNG hardware. The sample length register determines the number of samples to accumulate in a CRC register when generating a random number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks, so isn't this dependent on the value of length
in trng_get_bytes
?
What if the required length
will be larger than the total sample length defined in compilation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sample length register value in the HW is not the same as the length you pass into trng_get_bytes. For each random data byte trng_get_bytes requests from the HW, the HW would need to accumulate X number of samples (in this case it uses values derived from clock jitter) before outputting a value, and the sample length register sets this X value. That's why the driver has that bReady flag to indicate whether the accumulation is complete. TRNG_CNT_VAL and TRNG_PRESCALER together define this X value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry, but it's still not clear to me. X number of samples is a constant value, right? I mean, let's say every sample is 32 bit, and X would be 5, this means that every time you ask for random value, you will generate only 160 bits of entropy. Wht if the required random length is 180 bits? If I understand correct, the the bready
is set once 160 bits were accumulated, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value of X is not the number of entropy bits you want to generate. X is the number of sample accumulations the RNG hardware runs internally before outputting any entropy bits (the samples come from the clock jitter measurements). The bReady flag indicates the completion of this accumulation process, so when the flag is set, in the current configuration the RNG hardware returns 8-bits of entropy. In order to get 160 bits, the for loop in the trng_get_bytes function will need to loop through 20 times (the bReady flag will need to be set 20 times during this process), and for 180 bits, the loop will need to go through 23 iterations.
I am not sure whether I have answered your question. If you want to know how the hardware generates the entropy, you can have a look at chapter 13 of the processor reference manual:
http://www.analog.com/media/en/dsp-documentation/processor-manuals/ADuCM4050_HRM_0.2.pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that answers my question
for (i = 0; i < length; ) { | ||
// wait for the RNG ready to give a random number | ||
adi_rng_GetRdyStatus(RNGhDevice, &bRNGRdy); | ||
if (bRNGRdy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if bRNGRdy
will always be false? or some of the times? This means that you will miss some data, and go to next iteration
output[i++] = (uint8_t) nRandomNum; | ||
} | ||
} | ||
*output_length = length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see previous comment.
If you get bRNGRdy
will be fals some of the times, the collected output will not be length
, so you can't set the output size as length
, but you should set as the exact collected data length.
if (bRNGRdy) { | ||
// read the random number | ||
adi_rng_GetRngData(RNGhDevice, &nRandomNum); | ||
output[i++] = (uint8_t) nRandomNum; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
output
is a buffer of uint8_t
. nRandomNum
is uint32_t
. ALthough you downcast to uint8_t, I assume that adi_rng_GetRngData
collects 32 bits of entropy, but you take only 8 bits each time. You loose data this way, and it is likely that the output data will not have full entropy.
It is better to take the full random word and fill it in output
buffer, as long as it fits. if length
doesn't divide with sizeof(uint32_t)
. the last collection should only take part of the nRandomNum
value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some questions, but I am mostly not happy with the implementation of trng_get_bytes
. I suspect there are scenarios it will not produce good entropy
…ady; - Added a configuration call in trng_init to make sure the TRNG buffering mode is disabled, so only 8-bit bytes are returned; - Moved the TRNG device handle into the trng_t structure; - Fixed some formatting errors in the adc driver.
@0xc0170 Please label this as component:tls so we could track it |
adi_rng_Enable(RNGhDevice, true); | ||
|
||
// Save device handle | ||
obj->RNGhDevice = RNGhDevice; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RNGhDevice
is located on the stack. when you assign obj->RNGhDevice = RNGhDevice
you set obj->RNGhDevice
to be point to a variable on the stack, that might be garbage after exiting the function. Does adi_rng_Open
allocate memory on the heap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all the adi_xxx
functions return an error code? WHat happens if they fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dave-wu Please address the first comment\question that was hidden, It is still relevent
adi_rng_GetRngData(RNGhDevice, &nRandomNum); | ||
|
||
// Save the output | ||
output[i] = (uint8_t)nRandomNum; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as before. nRandomNum
is uint32_t
, and you are taking only 8 bits from it. THis doesn't gurantee sufficient entropy. I suggest you do the loop until i < length/sizeof(uint32_t)
, and the memcpy(((uint32_t*)output)[i],&nRandomNum, sizeof(uint32_t))
, and after the loop copy the residue (length%sizeof(uint32_t) bytes )
This will also result in fewer calls to Hardware, possibly improving performance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the return type of the adi_xxx
functions? Can they fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I failed to mention. The function adi_rng_GetRngData outputs either an 8-bit byte or a 32-bit word, depending on whether the TRNG buffering mode is enabled. By default the buffering mode is disabled and it would output an 8-bit byte, so only the LSB in nRandomNum is valid. In the trng_init, I added code to make sure the buffering mode is disabled.
The return values of the adi_xxx functions indicate whether the operation is success or had issues. In the case of adi_rng_GetRngData and adi_rng_GetRdyStatus calls, they would only return an error if the TRNG is not initialized in which case the device handle is invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default the buffering mode is disabled and it would output an 8-bit byte, so only the LSB in nRandomNum is valid.
I would use masking instead of casting
The return values of the adi_xxx functions indicate whether the operation is success or had issues.
In this case, it is better to check return type, and fail if the internal adi_xxx
fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will add error checking for the trng_get_byte function.
targets/targets.json
Outdated
"supported_toolchains": ["ARM", "GCC_ARM", "IAR"], | ||
"macros": ["__ADUCM4050__", "EV_COG_AD4050LZ"], | ||
"extra_labels": ["Analog_Devices", "ADUCM4X50", "ADUCM4050", "EV_COG_AD4050LZ", "FLASH_CMSIS_ALGO"], | ||
"device_has": ["SERIAL", "STDIO_MESSAGES", "TRNG", "SLEEP", "INTERRUPTIN", "LOWPOWERTIMER", "RTC", "SPI", "I2C", "FLASH", "ANALOGIN"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I2C is not fully implemented, why are some API missing? This might be case for some other HAL implementations (some functions are empty).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The I2C API's that are not implemented are due to the I2C hardware handling features such as start and stop. There is no way to create only a start or stop condition. Functions such as these are usually used in software I2C implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be stated in the code either via comment or git commit msg, I can see lot of empty functions but do not know the reason behind those (to support return 0 for instance). It would be helpful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments added to I2C and SPI modules as recommended.
{ | ||
obj->pin = pin; | ||
|
||
if (pin == (PinName)NC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be wrapped by {
and }
,same for the rest of if
in this file (one liners) (line 79, line 137)
uint32_t port = obj->pinname >> GPIO_PORT_SHIFT; | ||
uint32_t pin_num = obj->pinname & 0xFF; | ||
|
||
if (event == IRQ_NONE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
, also line 251 in this file, please align the code in HAL code files like this one
|
||
int i2c_byte_read(i2c_t *obj, int last) | ||
{ | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this limitation of hw or yet not implemented? Please provide more information. Leaving any API empty should have a reasoning .
static uart_irq_handler irq_handler = NULL; | ||
int stdio_uart_inited = 0; | ||
serial_t stdio_uart; | ||
int rxbuffer[2]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are these global? I can see these buffers are locally used in one function, could this be local scope then? not certain neither about why 2 are needed (based on the index), but if local scope would be, it would be just one character?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the buffers are moved to local, UART do not work properly. There are 2 UARTs on ADuCM4050, they may not run at the same baud rate. The spare UART is useful as a debug terminal or a wifi port. Do you want to disable the spare UART here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variables stdio_uart_inited and stdio_uart need to be global as they are referenced from mbed_board.c. The rxbuffer and txbuffers can be made static. As mentioned above, ADuCM4050 has two UARTs so it makes sense to provide code to support both even if only one is required for mbed-os.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood. if possible, should be local then, or at least these should be made privately to this compilation unit (static
).
} | ||
|
||
// if enable, set the bit otherwise clear the bit | ||
if (enable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
and }
around conditions
How was this target tested - can you share test results for all 3 toolchains? |
/morph export-build /morph uvisor-test |
Exporter Build : FAILUREBuild number : 85 |
@dave-wu Can you review the latest exporter build , fails for one exporter (blinky example) - undefined symbols in files that are being added here. |
@0xc0170 The error says it can't find uint16_t type definition, looks like it's an include path issue? What do I need to do to duplicate this test locally? |
From the log, this example fails:
therefore import blinky example, use your branch (this patch) as mbed-os lib . Export via |
@0xc0170 Those .c files listed in mbed-os\targets\TARGET_Analog_Devices\TARGET_ADUCM4X50\TARGET_ADUCM4050\.mbedignore have not been ignored by gnuarmeclipse project. This is why the makefile of make_gcc_arm can build. |
@dave-wu @li-ho Thanks for the pointer, https://github.com/dave-wu/mbed-os/blob/9e0e9c8bee1cc2b9d37ad8efbf4e1ea56cad8fff/targets/TARGET_Analog_Devices/TARGET_ADUCM4X50/TARGET_ADUCM4050/.mbedignore - I can see those files are failing for gnuarmeclipse exporter.
|
@0xc0170 and @theotherjimmy For example, adi_rtc_data.c is already included in adi_rtc.c, therefore, adi_rtc.c is the only file to be compiled in bsp\rtc folder. adi_rtc_data.c must not be compiled. |
@li-ho Please do not ignore files that will be used in the build. This will not export correctly on the website, regardless of what the offline exporters do. Could you refactor your code to avoid @0xc0170 While this may technically be a bug in the exporter, but I have yet to see a use case for single-file |
@theotherjimmy Those files in bsp folder come from AnalogDevices.ADuCM4x50_DFP.1.1.0.pack of https://www.keil.com/dd2/pack/, and they will be updated independently. I am disallowed to refactor them which will be different from the future pack. |
@theotherjimmy and @0xc0170 As mentioned earlier it is not ideal for us to change the driver code as it will be somewhat more complicated when it comes to update them to newer driver releases in the future. I believe this issue in the exporter should be fixed as the developer shouldn't have to re-organize source files just for the exporter to work. Not sure whether it is possible for the merge to proceed for now with the GNU exporter flagged as an issue to fix down the track? |
First of all, why some files are being ignored? I've just looked at bsp/rtc as its good example: How are you exporting your drivers to other enviroment like IAR, uVision, etc? Exluding those files from the workspace? What is the goal with this hierarchy introduced?
I do not believe this is a problem with exporters, rather software problem that our tests discovered. It can happen in any enviroment.
I understand and it's clear, no one would like to do magic for future maintainance, drag-n-drop! |
Rename adi_adc_data.c to adi_adc_data.h in adi_adc.c include adi_adc_data.h see attached zip file Let @dave-wu push the change. |
…icking up the ignored files; - Added #includes in BSP data C files so they can be built on their own without mbedignore;
@0xc0170 Changes pushed, please re-test. |
/morph export-build |
/morph build |
Build : SUCCESSBuild number : 476 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 97 |
Test : SUCCESSBuild number : 296 |
Notes:
Description
Added code to support the ADI EV-COG-AD4050LZ platform. Re-submitted as a new pull request to replace PR #5097.
Status
READY
Migrations
NO
Related PRs
N/A
Todos
N/A
Deploy notes
N/A
Steps to test or reproduce
N/A