Skip to content

Commit

Permalink
Device generator i2c (#29)
Browse files Browse the repository at this point in the history
* fixed indeterministic shuffle of contexts in MX_Device.h

* Added MX_Device.h path to add-path:

* fixed error in mxDevice_test.go

* Fixed old test

* Forgot to remove comment chars of t.Parallel

* switched secure and non secure mode
added tests
added download info from global.generator.yml

* Fixed formatting and lint complaints

* corrected wrong test for not set environment variable

* Removed fPaths again, they are not necessary, can used project directly
Added more tests

* removed a ;

* Added I2C filter extraction
more Tests

* changed formatting

* tried to fix a lint problem

* fixed publish coverage step

* fixed publish coverage step

* added output of command line
commented out reading of packs fro cbuild-gen.yml

---------

Co-authored-by: Sourabh Mehta <sourabh.mehta@arm.com>
  • Loading branch information
bgn42 and soumeh01 authored Mar 13, 2024
1 parent e9f35b9 commit 418f79b
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 98 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,4 @@ jobs:
with:
debug: true
coverageLocations: ./cover.out:gocov
prefix: github.com/open-cmsis-pack/generator-bridge
59 changes: 57 additions & 2 deletions cmd/commands/commands_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,62 @@
/*
* Copyright (c) 2023 Arm Limited. All rights reserved.
* Copyright (c) 2023-2024 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

package commands_test
package commands

import (
"bytes"
"testing"

"github.com/spf13/cobra"
)

func Test_configureGlobalCmd(t *testing.T) {
type args struct {
cmd *cobra.Command
args []string
}
tests := []struct {
name string
args args
wantErr bool
}{
{"test", args{cmd: &cobra.Command{}}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
NewCli()
if err := configureGlobalCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("configureGlobalCmd() %s error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
})
}
}

func Test_printVersionAndLicense(t *testing.T) {
tests := []struct {
name string
version string
copyright string
wantFile string
}{
{"test", "v1.2.3", "copy", "generator-bridge version 1.2.3 copy\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
file := &bytes.Buffer{}
saveVersion := Version
saveCopyright := Copyright
Version = tt.version
Copyright = tt.copyright
printVersionAndLicense(file)
if gotFile := file.String(); gotFile != tt.wantFile {
t.Errorf("printVersionAndLicense() %s = %v, want %v", tt.name, gotFile, tt.wantFile)
}
Version = saveVersion
Copyright = saveCopyright
})
}
}
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func main() {
utils.StartSignalWatcher()
start := time.Now()

log.Println("Command line:", os.Args[1:])

commands.Version = version
commands.Copyright = copyright
cmd := commands.NewCli()
Expand Down
18 changes: 9 additions & 9 deletions internal/cbuild/cbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type SubsystemType struct {
Compiler string
TrustZone string
CoreName string
Packs []PackType
// Packs []PackType
}

type ParamsType struct {
Expand Down Expand Up @@ -286,14 +286,14 @@ func ReadCbuildgen(name string, subsystem *SubsystemType) error {
log.Infof("Found CBuildGen: board: %v, device: %v, core: %v, TZ: %v, compiler: %v, project: %v",
subsystem.Board, subsystem.Device, subsystem.CoreName, subsystem.TrustZone, subsystem.Compiler, subsystem.Project)

for id := range cbuildGen.BuildGen.Packs {
genPack := cbuildGen.BuildGen.Packs[id]
var pack PackType
pack.Pack = genPack.Pack
pack.Path = genPack.Path
log.Infof("Found Pack: #%v Pack: %v, Path: %v", id, pack.Pack, pack.Path)
subsystem.Packs = append(subsystem.Packs, pack)
}
// for id := range cbuildGen.BuildGen.Packs {
// genPack := cbuildGen.BuildGen.Packs[id]
// var pack PackType
// pack.Pack = genPack.Pack
// pack.Path = genPack.Path
// log.Infof("Found Pack: #%v Pack: %v, Path: %v", id, pack.Pack, pack.Path)
// subsystem.Packs = append(subsystem.Packs, pack)
// }

return nil
}
45 changes: 41 additions & 4 deletions internal/common/common_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
/*
* Copyright (c) 2023 Arm Limited. All rights reserved.
* Copyright (c) 2023-2024 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

package common_test
package common

import "testing"
import (
"reflect"
"testing"
)

func TestFoo(t *testing.T) {
func TestReadYml(t *testing.T) {
type TestYml struct {
Test []struct {
Xx string `yaml:"xx"`
} `yaml:"test"`
}
var testyml TestYml

t1 := TestYml{Test: []struct {
Xx string `yaml:"xx"`
}{{Xx: "abc"}}}

type args struct {
path string
out interface{}
}
tests := []struct {
name string
args args
want TestYml
wantErr bool
}{
{"test", args{"../../testdata/test.yml", &testyml}, t1, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := ReadYml(tt.args.path, tt.args.out); (err != nil) != tt.wantErr {
t.Errorf("ReadYml() %s error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
xx := tt.want
if !reflect.DeepEqual(tt.args.out, &xx) {
t.Errorf("ReadYml() %s got = %v, want %v", tt.name, tt.args.out, tt.want)
}
})
}
}
24 changes: 21 additions & 3 deletions internal/stm32CubeMX/iniReader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,27 @@
* SPDX-License-Identifier: Apache-2.0
*/

package stm32cubemx_test
package stm32cubemx

import "testing"
func ExamplePrintKeyValStr() {
PrintKeyValStr("key", "val")
// Output:
//
// key : val
}

func ExamplePrintKeyValStrs() {
PrintKeyValStrs("key", []string{"val1", "val2"})
// Output:
//
// key
// 0: val1
// 1: val2
}

func TestIniReader(t *testing.T) {
func ExamplePrintKeyValInt() {
PrintKeyValInt("key", 4711)
// Output:
//
// key : 4711
}
104 changes: 83 additions & 21 deletions internal/stm32CubeMX/mxDevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,17 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error {
}

workDir := path.Dir(iocFile)
workDirAbs, err := filepath.Abs(workDir)
if err != nil {
return err
}

mspName := deviceFamily + "xx_hal_msp.c"
// pinConfigMap, err := createPinConfigMap(mspName)
mspFolder := contextMap["ProjectManager"]["MainLocation"]
if mspFolder == "" {
mainFolder := contextMap["ProjectManager"]["MainLocation"]
if mainFolder == "" {
return errors.New("main location missing")
}
mspName := deviceFamily + "xx_hal_msp.c"

var cfgPath string
if len(contexts) == 0 {
msp := path.Join(workDirAbs, mspFolder, mspName)
cfgPath = path.Join("drv_cfg", params.Subsystem[0].SubsystemIdx.Project)
err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, "", params)
err := writeMXdeviceH(contextMap, workDir, mainFolder, mspName, cfgPath, "", params)
if err != nil {
return err
}
Expand Down Expand Up @@ -98,7 +92,6 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error {
if len(contextFolder) == 0 {
return errors.New("Cannot find context " + context)
}
msp := path.Join(workDirAbs, contextFolder, mspFolder, mspName)
for _, subsystem := range params.Subsystem {
if subsystem.CoreName == coreName {
if len(subsystem.TrustZone) == 0 {
Expand All @@ -111,7 +104,7 @@ func ReadContexts(iocFile string, params cbuild.ParamsType) error {
}
}
}
err := writeMXdeviceH(contextMap, workDir, msp, cfgPath, context, params)
err := writeMXdeviceH(contextMap, workDir, path.Join(contextFolder, mainFolder), mspName, cfgPath, context, params)
if err != nil {
return err
}
Expand Down Expand Up @@ -147,7 +140,20 @@ func createContextMap(iocFile string) (map[string]map[string]string, error) {
return contextMap, nil
}

func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp string, cfgPath string, context string, params cbuild.ParamsType) error {
func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, mainFolder string, mspName string, cfgPath string, context string, params cbuild.ParamsType) error {
workDirAbs, err := filepath.Abs(workDir)
if err != nil {
return err
}

main := path.Join(workDirAbs, mainFolder, "main.c")
fMain, err := os.Open(main)
if err != nil {
return err
}
defer fMain.Close()

msp := path.Join(workDirAbs, mainFolder, mspName)
fMsp, err := os.Open(msp)
if err != nil {
return err
Expand Down Expand Up @@ -181,11 +187,15 @@ func writeMXdeviceH(contextMap map[string]map[string]string, workDir string, msp
}
for _, peripheral := range peripherals {
vmode := getVirtualMode(contextMap, peripheral)
i2cInfo, err := getI2cInfo(fMain, peripheral)
if err != nil {
return err
}
pins, err := getPins(contextMap, fMsp, peripheral)
if err != nil {
return err
}
err = mxDeviceWritePeripheralCfg(out, peripheral, vmode, pins)
err = mxDeviceWritePeripheralCfg(out, peripheral, vmode, i2cInfo, pins)
if err != nil {
return err
}
Expand Down Expand Up @@ -361,6 +371,46 @@ func getDigitAtEnd(pin string) string {
return ""
}

// Get i2c info (filter, coefficients)
func getI2cInfo(fMain *os.File, peripheral string) (map[string]string, error) {
info := make(map[string]string)
if strings.HasPrefix(peripheral, "I2C") {
_, err := fMain.Seek(0, 0)
if err != nil {
return nil, err
}
section := false

mainScan := bufio.NewScanner(fMain)
mainScan.Split(bufio.ScanLines)
for mainScan.Scan() {
line := mainScan.Text()
if !section {
if strings.HasPrefix(line, "static void MX_"+peripheral+"_Init") && !strings.Contains(line, ";") {
section = true // Start of section: static void MX_I2Cx_Init
}
} else { // Parse section: static void MX_I2Cx_Init
if strings.HasPrefix(line, "}") {
break // End of section: static void MX_I2Cx_Init
}
if strings.Contains(line, "HAL_I2CEx_ConfigAnalogFilter") {
if strings.Contains(line, "I2C_ANALOGFILTER_ENABLE") {
info["ANF_ENABLE"] = "1"
} else {
info["ANF_ENABLE"] = "0"
}
}
if strings.Contains(line, "HAL_I2CEx_ConfigDigitalFilter") {
dnf := strings.Split(strings.Split(line, ",")[1], ")")[0]
dnf = strings.TrimRight(strings.TrimLeft(dnf, "\t "), "\t ")
info["DNF"] = dnf
}
}
}
}
return info, nil
}

func getPinConfiguration(fMsp *os.File, peripheral string, pin string, label string) (PinDefinition, error) {
var pinInfo PinDefinition

Expand Down Expand Up @@ -473,19 +523,33 @@ func mxDeviceWriteHeader(out *bufio.Writer, fName string) error {
return err
}

func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode string, pins map[string]PinDefinition) error {
func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode string, i2cInfo map[string]string, pins map[string]PinDefinition) error {
var err error

str := "\n/*------------------------------ " + peripheral
if len(str) < 49 {
str += strings.Repeat(" ", 49-len(str))
}
str += "-----------------------------*/\n"
_, err := out.WriteString(str)
if err != nil {
if _, err = out.WriteString(str); err != nil {
return err
}
if err = writeDefine(out, peripheral, "1\n"); err != nil {
return err
}
if i2cInfo != nil {
if _, err = out.WriteString("/* Filter Settings */\n"); err != nil {
return err
}
for item, value := range i2cInfo {
if err = writeDefine(out, peripheral+"_"+item, value); err != nil {
return err
}
}
if _, err = out.WriteString("\n"); err != nil {
return err
}
}
if vmode != "" {
if _, err = out.WriteString("/* Virtual mode */\n"); err != nil {
return err
Expand All @@ -498,13 +562,11 @@ func mxDeviceWritePeripheralCfg(out *bufio.Writer, peripheral string, vmode stri
}
}
if len(pins) != 0 {
_, err = out.WriteString("/* Pins */\n")
if err != nil {
if _, err = out.WriteString("/* Pins */\n"); err != nil {
return err
}
for pin, pinDef := range pins {
_, err = out.WriteString("\n/* " + pin + " */\n")
if err != nil {
if _, err = out.WriteString("\n/* " + pin + " */\n"); err != nil {
return err
}
if err = writeDefine(out, pin+"_Pin", pinDef.p); err != nil {
Expand Down
Loading

0 comments on commit 418f79b

Please sign in to comment.