diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 80b4aeb50..7de329e48 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -140,11 +140,13 @@ jobs: - name: ArduinoBLE - name: ArduinoGraphics - name: Arduino_GigaDisplayTouch + - name: arducam_dvp additional-sketch-paths: | - libraries/PDM - libraries/MCUboot - libraries/Camera/examples/CameraCaptureRawBytes - libraries/Camera/examples/CameraMotionDetect + - libraries/Camera/examples/GigaCameraDisplay - libraries/Portenta_SDCARD - libraries/Portenta_SDRAM - libraries/Arduino_H7_Video diff --git a/boards.txt b/boards.txt index 112e3f502..6a067f06c 100644 --- a/boards.txt +++ b/boards.txt @@ -581,6 +581,9 @@ opta.menu.split.100_0=2MB M7 opta.menu.split.75_25=1.5MB M7 + 0.5MB M4 opta.menu.split.50_50=1MB M7 + 1MB M4 +opta.menu.security.none=None +opta.menu.security.sien=Signature + Encryption + opta.menu.target_core.cm7.build.variant=OPTA opta.menu.target_core.cm7.build.mcu=cortex-m7 opta.menu.target_core.cm7.build.fpu=-mfpu=fpv5-d16 @@ -593,15 +596,23 @@ opta.menu.target_core.cm4.build.fpu=-mfpu=fpv4-sp-d16 opta.menu.target_core.cm4.build.architecture=cortex-m4 opta.menu.target_core.cm4.compiler.mbed.arch.define=-DOPTA_PINS +opta.build.float-abi=-mfloat-abi=softfp +opta.build.extra_flags= opta.menu.split.50_50.build.extra_ldflags=-DCM4_BINARY_START=0x08100000 -DCM4_BINARY_END=0x08200000 opta.menu.split.75_25.build.extra_ldflags=-DCM4_BINARY_START=0x08180000 -DCM4_BINARY_END=0x08200000 opta.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000 -DCM4_BINARY_END=0x60040000 -DCM4_RAM_END=0x60080000 -opta.build.board={build.variant} -opta.build.extra_flags= -opta.build.float-abi=-mfloat-abi=softfp +opta.build.board={build.variant} opta.build.ldscript=linker_script.ld opta.compiler.mbed.arch.define= +opta.build.slot_size=0x1E0000 +opta.build.header_size=0x20000 +opta.build.alignment=32 +opta.build.version=1.2.3+4 +opta.menu.security.sien.recipe.hooks.objcopy.postobjcopy.1.pattern="{tools.imgtool.path}/{tools.imgtool.cmd}" {tools.imgtool.flags} +opta.menu.security.sien.build.keys.keychain={runtime.platform.path}/libraries/MCUboot/default_keys +opta.menu.security.sien.build.keys.sign_key=ecdsa-p256-signing-priv-key.pem +opta.menu.security.sien.build.keys.encrypt_key=ecdsa-p256-encrypt-pub-key.pem opta.compiler.mbed.defines={build.variant.path}/defines.txt opta.compiler.mbed.ldflags={build.variant.path}/ldflags.txt opta.compiler.mbed.cflags={build.variant.path}/cflags.txt @@ -653,10 +664,15 @@ opta.upload.interface=0 opta.upload.use_1200bps_touch=true opta.upload.wait_for_upload_port=true opta.upload.native_usb=true -opta.upload.maximum_size=786432 +opta.upload.maximum_size=1966080 opta.upload.maximum_data_size=523624 -opta.menu.target_core.cm7.upload.address=0x08040000 +opta.menu.security.none.upload.interface=0 +opta.menu.security.sien.upload.interface=2 + +opta.menu.security.none.upload.address_m7=0x08040000 +opta.menu.security.sien.upload.address_m7=0xA0000000 +opta.menu.target_core.cm7.upload.address={upload.address_m7} opta.menu.target_core.cm7.menu.split.50_50.upload.maximum_size=786432 opta.menu.target_core.cm7.menu.split.75_25.upload.maximum_size=1441792 diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h new file mode 100644 index 000000000..2850a8e95 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 Nuvoton Technology Corp. + * Copyright (c) 2022 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Description: M460 EMAC driver header file + */ + +#include "numaker_emac_config.h" +#include "M460.h" +#ifndef _M460_ETH_ +#define _M460_ETH_ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x07c0 /* Unused... */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define PACKET_BUFFER_SIZE ( NU_ETH_MAX_FLEN + ((NU_ETH_MAX_FLEN%4) ? (4 - (NU_ETH_MAX_FLEN%4)) : 0) ) //For DMA 4 bytes alignment + +#define CONFIG_PHY_ADDR 1 + + +#endif /* _M460_ETH_ */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h new file mode 100644 index 000000000..4410ea744 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h @@ -0,0 +1,1500 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/**\file + * This file defines the function prototypes for the Synopsys GMAC device and the + * Marvell 88E1011/88E1011S integrated 10/100/1000 Gigabit Ethernet Transceiver. + * Since the phy register mapping are standardised, the phy register map and the + * bit definitions remain the same for other phy as well. + * This also defines some of the Ethernet related parmeters. + * \internal + * -----------------------------REVISION HISTORY------------------------------------ + * Synopsys 01/Aug/2007 Created + */ + + +#ifndef SYNOP_GMAC_DEV_H +#define SYNOP_GMAC_DEV_H 1 + +#include "synopGMAC_plat.h" + +#define GMAC_CNT 1 + +/*SynopGMAC can support up to 32 phys*/ + +enum GMACPhyBase { + PHY0 = 0, //The device can support 32 phys, but we use first phy only + PHY1 = 1, + PHY31 = 31, +}; + +#define DEFAULT_PHY_BASE PHY1 //We use First Phy + +#define GMAC0MappedAddr EMAC_BASE //0x40012000 +#define GMAC1MappedAddr EMAC_BASE +#define MACBASE 0x0000 // The Mac Base address offset is 0x0000 +#define DMABASE 0x1000 // Dma base address starts with an offset 0x1000 + + +#define TRANSMIT_DESC_SIZE 8//256 //Tx Descriptors needed in the Descriptor pool/queue +#define RECEIVE_DESC_SIZE 16//256 //Rx Descriptors needed in the Descriptor pool/queue + +#define ETHERNET_HEADER 14 //6 byte Dest addr, 6 byte Src addr, 2 byte length/type +#define ETHERNET_CRC 4 //Ethernet CRC +#define ETHERNET_EXTRA 2 //Only God knows about this????? +#define ETHERNET_PACKET_COPY 250 // Maximum length when received data is copied on to a new skb +#define ETHERNET_PACKET_EXTRA 18 // Preallocated length for the rx packets is MTU + ETHERNET_PACKET_EXTRA +#define VLAN_TAG 4 //optional 802.1q VLAN Tag +#define MIN_ETHERNET_PAYLOAD 46 //Minimum Ethernet payload size +#define MAX_ETHERNET_PAYLOAD 1500 //Maximum Ethernet payload size +#define JUMBO_FRAME_PAYLOAD 9000 //Jumbo frame payload size + +#define TX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG + + +// This is the IP's phy address. This is unique address for every MAC in the universe +#define DEFAULT_MAC0_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7} +#define DEFAULT_MAC1_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF8} +/* +DMA Descriptor Structure +The structure is common for both receive and transmit descriptors +The descriptor is of 4 words, but our structrue contains 6 words where +last two words are to hold the virtual address of the network buffer pointers +for driver's use +From the GMAC core release 3.50a onwards, the Enhanced Descriptor structure got changed. +The descriptor (both transmit and receive) are of 8 words each rather the 4 words of normal +descriptor structure. +Whenever IEEE 1588 Timestamping is enabled TX/RX DESC6 provides the lower 32 bits of Timestamp value and + TX/RX DESC7 provides the upper 32 bits of Timestamp value +In addition to this whenever extended status bit is set (RX DESC0 bit 0), RX DESC4 contains the extended status information +*/ + +#define MODULO_INTERRUPT 1 // if it is set to 1, interrupt is available for all the descriptors or else interrupt is available only for +// descriptor whose index%MODULO_INTERRUPT is zero +typedef struct DmaDescStruct { + u32 status; /* Status */ + u32 length; /* Buffer 1 and Buffer 2 length */ + u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */ + u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */ + /* This data below is used only by driver */ + u32 extstatus; /* Extended status of a Rx Descriptor */ + u32 reserved1; /* Reserved word */ + u32 timestamplow; /* Lower 32 bits of the 64 bit timestamp value */ + u32 timestamphigh; /* Higher 32 bits of the 64 bit timestamp value */ + //u32 data1; /* This holds virtual address of buffer1, not used by DMA */ + //u32 data2; /* This holds virtual address of buffer2, not used by DMA */ +} DmaDesc; + +enum DescMode { + RINGMODE = 0x00000001, + CHAINMODE = 0x00000002, +}; + +enum BufferMode { + SINGLEBUF = 0x00000001, + DUALBUF = 0x00000002, +}; + +typedef u32 * dma_addr_t; + +/* synopGMAC device data */ + +struct sk_buff { + unsigned char data[2048]; + unsigned int len; + unsigned int volatile rdy; +}; + +struct net_device_stats { + u32 tx_bytes; + u32 tx_packets; + u32 tx_errors; + u32 tx_aborted_errors; + u32 tx_carrier_errors; + u32 tx_ip_header_errors; + u32 tx_ip_payload_errors; + u32 collisions; + u32 rx_bytes; + u32 rx_packets; + u32 rx_errors; + u32 rx_crc_errors; + u32 rx_frame_errors; + u32 rx_length_errors; + u32 rx_dropped; + u32 rx_over_errors; + u32 rx_ip_header_errors; + u32 rx_ip_payload_errors; + volatile u32 ts_int; +}; + +typedef struct synopGMACDeviceStruct { + u64 MacBase; /* base address of MAC registers */ + u64 DmaBase; /* base address of DMA registers */ + u64 PhyBase; /* PHY device address on MII interface */ + u64 Version; /* Gmac Revision version */ + + + /*dma_addr_t*/ DmaDesc *TxDescDma; /* Dma-able address of first tx descriptor either in ring or chain mode, this is used by the GMAC device*/ + /*dma_addr_t*/ DmaDesc *RxDescDma; /* Dma-albe address of first rx descriptor either in ring or chain mode, this is used by the GMAC device*/ + DmaDesc *TxDesc; /* start address of TX descriptors ring or chain, this is used by the driver */ + DmaDesc *RxDesc; /* start address of RX descriptors ring or chain, this is used by the driver */ + + u32 BusyTxDesc; /* Number of Tx Descriptors owned by DMA at any given time*/ + u32 BusyRxDesc; /* Number of Rx Descriptors owned by DMA at any given time*/ + + u32 RxDescCount; /* number of rx descriptors in the tx descriptor queue/pool */ + u32 TxDescCount; /* number of tx descriptors in the rx descriptor queue/pool */ + + u32 TxBusy; /* index of the tx descriptor owned by DMA, is obtained by synopGMAC_get_tx_qptr() */ + u32 TxNext; /* index of the tx descriptor next available with driver, given to DMA by synopGMAC_set_tx_qptr() */ + u32 RxBusy; /* index of the rx descriptor owned by DMA, obtained by synopGMAC_get_rx_qptr() */ + u32 RxNext; /* index of the rx descriptor next available with driver, given to DMA by synopGMAC_set_rx_qptr() */ + + DmaDesc * TxBusyDesc; /* Tx Descriptor address corresponding to the index TxBusy */ + DmaDesc * TxNextDesc; /* Tx Descriptor address corresponding to the index TxNext */ + DmaDesc * RxBusyDesc; /* Rx Descriptor address corresponding to the index TxBusy */ + DmaDesc * RxNextDesc; /* Rx Descriptor address corresponding to the index RxNext */ + + + /*Phy related stuff*/ + u32 ClockDivMdc; /* Clock divider value programmed in the hardware */ + /* The status of the link */ + u32 LinkState; /* Link status as reported by the Marvel Phy */ + u32 DuplexMode; /* Duplex mode of the Phy */ + u32 Speed; /* Speed of the Phy */ + u32 LoopBackMode; /* Loopback status of the Phy */ + u32 Intf; + struct net_device_stats synopGMACNetStats; + + u32 tx_sec; + u32 tx_subsec; + u32 rx_sec; + u32 rx_subsec; + + u32 GMAC_Power_down; + +} synopGMACdevice; + + +/* Below is "88E1011/88E1011S Integrated 10/100/1000 Gigabit Ethernet Transceiver" + * Register and their layouts. This Phy has been used in the Dot Aster GMAC Phy daughter. + * Since the Phy register map is standard, this map hardly changes to a different Ppy + */ + +enum MiiRegisters { + PHY_CONTROL_REG = 0x0000, /*Control Register*/ + PHY_STATUS_REG = 0x0001, /*Status Register */ + PHY_ID_HI_REG = 0x0002, /*PHY Identifier High Register*/ + PHY_ID_LOW_REG = 0x0003, /*PHY Identifier High Register*/ + PHY_AN_ADV_REG = 0x0004, /*Auto-Negotiation Advertisement Register*/ + PHY_LNK_PART_ABl_REG = 0x0005, /*Link Partner Ability Register (Base Page)*/ + PHY_AN_EXP_REG = 0x0006, /*Auto-Negotiation Expansion Register*/ + PHY_AN_NXT_PAGE_TX_REG = 0x0007, /*Next Page Transmit Register*/ + PHY_LNK_PART_NXT_PAGE_REG = 0x0008, /*Link Partner Next Page Register*/ + PHY_1000BT_CTRL_REG = 0x0009, /*1000BASE-T Control Register*/ + PHY_1000BT_STATUS_REG = 0x000a, /*1000BASE-T Status Register*/ + PHY_SPECIFIC_CTRL_REG = 0x0010, /*Phy specific control register*/ + PHY_SPECIFIC_STATUS_REG = 0x0011, /*Phy specific status register*/ + PHY_INTERRUPT_ENABLE_REG = 0x0012, /*Phy interrupt enable register*/ + PHY_INTERRUPT_STATUS_REG = 0x0013, /*Phy interrupt status register*/ + PHY_EXT_PHY_SPC_CTRL = 0x0014, /*Extended Phy specific control*/ + PHY_RX_ERR_COUNTER = 0x0015, /*Receive Error Counter*/ + PHY_EXT_ADDR_CBL_DIAG = 0x0016, /*Extended address for cable diagnostic register*/ + PHY_LED_CONTROL = 0x0018, /*LED Control*/ + PHY_MAN_LED_OVERIDE = 0x0019, /*Manual LED override register*/ + PHY_EXT_PHY_SPC_CTRL2 = 0x001a, /*Extended Phy specific control 2*/ + PHY_EXT_PHY_SPC_STATUS = 0x001b, /*Extended Phy specific status*/ + PHY_CBL_DIAG_REG = 0x001c, /*Cable diagnostic registers*/ +}; + + +/* This is Control register layout. Control register is of 16 bit wide. +*/ + +enum Mii_GEN_CTRL { + /* Description bits R/W default value */ + Mii_reset = 0x8000, + Mii_Speed_10 = 0x0000, /* 10 Mbps 6:13 RW */ + Mii_Speed_100 = 0x2000, /* 100 Mbps 6:13 RW */ + Mii_Speed_1000 = 0x0040, /* 1000 Mbit/s 6:13 RW */ + + Mii_Duplex = 0x0100, /* Full Duplex mode 8 RW */ + + Mii_Manual_Master_Config = 0x0800, /* Manual Master Config 11 RW */ + + Mii_Loopback = 0x4000, /* Enable Loop back 14 RW */ + Mii_NoLoopback = 0x0000, /* Enable Loop back 14 RW */ +}; + +enum Mii_Phy_Status { + Mii_phy_status_speed_10 = 0x0000, + Mii_phy_status_speed_100 = 0x4000, + Mii_phy_status_speed_1000 = 0x8000, + + Mii_phy_status_full_duplex = 0x2000, + Mii_phy_status_half_duplex = 0x0000, + + Mii_phy_status_link_up = 0x0400, +}; +/* This is Status register layout. Status register is of 16 bit wide. +*/ +enum Mii_GEN_STATUS { + Mii_AutoNegCmplt = 0x0020, /* Autonegotiation completed 5 RW */ + Mii_Link = 0x0004, /* Link status 2 RW */ +}; + +enum Mii_Link_Status { + LINKDOWN = 0, + LINKUP = 1, +}; + +enum Mii_Duplex_Mode { + HALFDUPLEX = 1, + FULLDUPLEX = 2, +}; +enum Mii_Link_Speed { + SPEED10 = 1, + SPEED100 = 2, + SPEED1000 = 3, +}; + +enum Mii_Loop_Back { + NOLOOPBACK = 0, + LOOPBACK = 1, +}; + + + +/********************************************************** + * GMAC registers Map + * For Pci based system address is BARx + GmacRegisterBase + * For any other system translation is done accordingly + **********************************************************/ +enum GmacRegisters { + GmacConfig = 0x0000, /* Mac config Register */ + GmacFrameFilter = 0x0004, /* Mac frame filtering controls */ + GmacHashHigh = 0x0008, /* Multi-cast hash table high */ + GmacHashLow = 0x000C, /* Multi-cast hash table low */ + GmacGmiiAddr = 0x0010, /* GMII address Register(ext. Phy) */ + GmacGmiiData = 0x0014, /* GMII data Register(ext. Phy) */ + GmacFlowControl = 0x0018, /* Flow control Register */ + GmacVlan = 0x001C, /* VLAN tag Register (IEEE 802.1Q) */ + + GmacVersion = 0x0020, /* GMAC Core Version Register */ + GmacDebug = 0x0024, /* GMAC Debug Register */ + GmacWakeupAddr = 0x0028, /* GMAC wake-up frame filter adrress reg */ + GmacPmtCtrlStatus = 0x002C, /* PMT control and status register */ + + + GmacLPICtrlSts = 0x0030, /* LPI (low power idle) Control and Status Register */ + GmacLPITimerCtrl = 0x0034, /* LPI timer control register */ + + + GmacInterruptStatus = 0x0038, /* Mac Interrupt ststus register */ + GmacInterruptMask = 0x003C, /* Mac Interrupt Mask register */ + + GmacAddr0High = 0x0040, /* Mac address0 high Register */ + GmacAddr0Low = 0x0044, /* Mac address0 low Register */ + GmacAddr1High = 0x0048, /* Mac address1 high Register */ + GmacAddr1Low = 0x004C, /* Mac address1 low Register */ + GmacAddr2High = 0x0050, /* Mac address2 high Register */ + GmacAddr2Low = 0x0054, /* Mac address2 low Register */ + GmacAddr3High = 0x0058, /* Mac address3 high Register */ + GmacAddr3Low = 0x005C, /* Mac address3 low Register */ + GmacAddr4High = 0x0060, /* Mac address4 high Register */ + GmacAddr4Low = 0x0064, /* Mac address4 low Register */ + GmacAddr5High = 0x0068, /* Mac address5 high Register */ + GmacAddr5Low = 0x006C, /* Mac address5 low Register */ + GmacAddr6High = 0x0070, /* Mac address6 high Register */ + GmacAddr6Low = 0x0074, /* Mac address6 low Register */ + GmacAddr7High = 0x0078, /* Mac address7 high Register */ + GmacAddr7Low = 0x007C, /* Mac address7 low Register */ + GmacAddr8High = 0x0080, /* Mac address8 high Register */ + GmacAddr8Low = 0x0084, /* Mac address8 low Register */ + GmacAddr9High = 0x0088, /* Mac address9 high Register */ + GmacAddr9Low = 0x008C, /* Mac address9 low Register */ + GmacAddr10High = 0x0090, /* Mac address10 high Register */ + GmacAddr10Low = 0x0094, /* Mac address10 low Register */ + GmacAddr11High = 0x0098, /* Mac address11 high Register */ + GmacAddr11Low = 0x009C, /* Mac address11 low Register */ + GmacAddr12High = 0x00A0, /* Mac address12 high Register */ + GmacAddr12Low = 0x00A4, /* Mac address12 low Register */ + GmacAddr13High = 0x00A8, /* Mac address13 high Register */ + GmacAddr13Low = 0x00AC, /* Mac address13 low Register */ + GmacAddr14High = 0x00B0, /* Mac address14 high Register */ + GmacAddr14Low = 0x00B4, /* Mac address14 low Register */ + GmacAddr15High = 0x00B8, /* Mac address15 high Register */ + GmacAddr15Low = 0x00BC, /* Mac address15 low Register */ + GmacRgmiiCtrlSts = 0x00D8, /*SGMII_RGMII_SMII_Control_Status Register */ + GmacVLANIncRep = 0x0584, + /*Time Stamp Register Map*/ + GmacTSControl = 0x0700, /* Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ + + GmacTSSubSecIncr = 0x0704, /* 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHigh = 0x0708, /* 32 bit seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLow = 0x070C, /* 32 bit nano seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighUpdate = 0x0710, /* 32 bit seconds(MS) to be written/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLowUpdate = 0x0714, /* 32 bit nano seconds(MS) to be writeen/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSAddend = 0x0718, /* Used by Software to readjust the clock frequency linearly : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSTargetTimeHigh = 0x071C, /* 32 bit seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSTargetTimeLow = 0x0720, /* 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighWord = 0x0724, /* Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ + //GmacTSHighWordUpdate = 0x072C, /* Time Stamp Higher Word Update Register (Version 2 only); only lower 16 bits are valid */ + + GmacTSStatus = 0x0728, /* Time Stamp Status Register */ + GmacPPSCtrl = 0x072C, /* PPS Control Register */ + GmacPPSInt = 0x0760, /* PPS0 Interval Register */ + GmacPPSWidth = 0x0764, /* PPS0 Width Register */ +}; + +/********************************************************** + * GMAC Network interface registers + * This explains the Register's Layout + + * FES is Read only by default and is enabled only when Tx + * Config Parameter is enabled for RGMII/SGMII interface + * during CoreKit Config. + + * DM is Read only with value 1'b1 in Full duplex only Config + **********************************************************/ + +/* GmacConfig = 0x0000, Mac config Register Layout */ +enum GmacConfigReg { + /* Bit description Bits R/W Reset value */ + + GmacSrcAddrInsRpl = 0x70000000, + GmacSrcAddrIns = 0x20000000, + GmacSrcAddrRpl = 0x30000000, + GmacWatchdog = 0x00800000, + GmacWatchdogDisable = 0x00800000, /* (WD)Disable watchdog timer on Rx 23 RW */ + GmacWatchdogEnable = 0x00000000, /* Enable watchdog timer 0 */ + + GmacJabber = 0x00400000, + GmacJabberDisable = 0x00400000, /* (JD)Disable jabber timer on Tx 22 RW */ + GmacJabberEnable = 0x00000000, /* Enable jabber timer 0 */ + + GmacFrameBurst = 0x00200000, + GmacFrameBurstEnable = 0x00200000, /* (BE)Enable frame bursting during Tx 21 RW */ + GmacFrameBurstDisable = 0x00000000, /* Disable frame bursting 0 */ + + GmacJumboFrame = 0x00100000, + GmacJumboFrameEnable = 0x00100000, /* (JE)Enable jumbo frame for Tx 20 RW */ + GmacJumboFrameDisable = 0x00000000, /* Disable jumbo frame 0 */ + + GmacInterFrameGap7 = 0x000E0000, /* (IFG) Config7 - 40 bit times 19:17 RW */ + GmacInterFrameGap6 = 0x000C0000, /* (IFG) Config6 - 48 bit times */ + GmacInterFrameGap5 = 0x000A0000, /* (IFG) Config5 - 56 bit times */ + GmacInterFrameGap4 = 0x00080000, /* (IFG) Config4 - 64 bit times */ + GmacInterFrameGap3 = 0x00040000, /* (IFG) Config3 - 72 bit times */ + GmacInterFrameGap2 = 0x00020000, /* (IFG) Config2 - 80 bit times */ + GmacInterFrameGap1 = 0x00010000, /* (IFG) Config1 - 88 bit times */ + GmacInterFrameGap0 = 0x00000000, /* (IFG) Config0 - 96 bit times 000 */ + + GmacDisableCrs = 0x00010000, + GmacMiiGmii = 0x00008000, + GmacSelectMii = 0x00008000, /* (PS)Port Select-MII mode 15 RW */ + GmacSelectGmii = 0x00000000, /* GMII mode 0 */ + + GmacFESpeed100 = 0x00004000, /*(FES)Fast Ethernet speed 100Mbps 14 RW */ + GmacFESpeed10 = 0x00000000, /* 10Mbps 0 */ + + GmacRxOwn = 0x00002000, + GmacDisableRxOwn = 0x00002000, /* (DO)Disable receive own packets 13 RW */ + GmacEnableRxOwn = 0x00000000, /* Enable receive own packets 0 */ + + GmacLoopback = 0x00001000, + GmacLoopbackOn = 0x00001000, /* (LM)Loopback mode for GMII/MII 12 RW */ + GmacLoopbackOff = 0x00000000, /* Normal mode 0 */ + + GmacDuplex = 0x00000800, + GmacFullDuplex = 0x00000800, /* (DM)Full duplex mode 11 RW */ + GmacHalfDuplex = 0x00000000, /* Half duplex mode 0 */ + + GmacRxIpcOffload = 0x00000400, /*IPC checksum offload 10 RW 0 */ + + GmacRetry = 0x00000200, + GmacRetryDisable = 0x00000200, /* (DR)Disable Retry 9 RW */ + GmacRetryEnable = 0x00000000, /* Enable retransmission as per BL 0 */ + + GmacLinkUp = 0x00000100, /* (LUD)Link UP 8 RW */ + GmacLinkDown = 0x00000100, /* Link Down 0 */ + + GmacPadCrcStrip = 0x00000080, + GmacPadCrcStripEnable = 0x00000080, /* (ACS) Automatic Pad/Crc strip enable 7 RW */ + GmacPadCrcStripDisable = 0x00000000, /* Automatic Pad/Crc stripping disable 0 */ + + GmacBackoffLimit = 0x00000060, + GmacBackoffLimit3 = 0x00000060, /* (BL)Back-off limit in HD mode 6:5 RW */ + GmacBackoffLimit2 = 0x00000040, /* */ + GmacBackoffLimit1 = 0x00000020, /* */ + GmacBackoffLimit0 = 0x00000000, /* 00 */ + + GmacDeferralCheck = 0x00000010, + GmacDeferralCheckEnable = 0x00000010, /* (DC)Deferral check enable in HD mode 4 RW */ + GmacDeferralCheckDisable = 0x00000000, /* Deferral check disable 0 */ + + GmacTx = 0x00000008, + GmacTxEnable = 0x00000008, /* (TE)Transmitter enable 3 RW */ + GmacTxDisable = 0x00000000, /* Transmitter disable 0 */ + + GmacRx = 0x00000004, + GmacRxEnable = 0x00000004, /* (RE)Receiver enable 2 RW */ + GmacRxDisable = 0x00000000, /* Receiver disable 0 */ +}; + +/* GmacFrameFilter = 0x0004, Mac frame filtering controls Register Layout*/ +enum GmacFrameFilterReg { + GmacFilter = 0x80000000, + GmacFilterOff = 0x80000000, /* (RA)Receive all incoming packets 31 RW */ + GmacFilterOn = 0x00000000, /* Receive filtered packets only 0 */ + GmacVlanTagFilter = 0x00010000, /*VLAN tag filter enable 16 RW 0 */ + GmacHashPerfectFilter = 0x00000400, /*Hash or Perfect Filter enable 10 RW 0 */ + + GmacSrcAddrFilter = 0x00000200, + GmacSrcAddrFilterEnable = 0x00000200, /* (SAF)Source Address Filter enable 9 RW */ + GmacSrcAddrFilterDisable = 0x00000000, /* 0 */ + + GmacSrcInvaAddrFilter = 0x00000100, + GmacSrcInvAddrFilterEn = 0x00000100, /* (SAIF)Inv Src Addr Filter enable 8 RW */ + GmacSrcInvAddrFilterDis = 0x00000000, /* 0 */ + + GmacPassControl = 0x000000C0, + GmacPassControl3 = 0x000000C0, /* (PCS)Forwards ctrl frms that pass AF 7:6 RW */ + GmacPassControl2 = 0x00000080, /* Forwards all control frames */ + GmacPassControl1 = 0x00000040, /* Does not pass control frames */ + GmacPassControl0 = 0x00000000, /* Does not pass control frames 00 */ + + GmacBroadcast = 0x00000020, + GmacBroadcastDisable = 0x00000020, /* (DBF)Disable Rx of broadcast frames 5 RW */ + GmacBroadcastEnable = 0x00000000, /* Enable broadcast frames 0 */ + + GmacMulticastFilter = 0x00000010, + GmacMulticastFilterOff = 0x00000010, /* (PM) Pass all multicast packets 4 RW */ + GmacMulticastFilterOn = 0x00000000, /* Pass filtered multicast packets 0 */ + + GmacDestAddrFilter = 0x00000008, + GmacDestAddrFilterInv = 0x00000008, /* (DAIF)Inverse filtering for DA 3 RW */ + GmacDestAddrFilterNor = 0x00000000, /* Normal filtering for DA 0 */ + + GmacMcastHashFilter = 0x00000004, + GmacMcastHashFilterOn = 0x00000004, /* (HMC)perfom multicast hash filtering 2 RW */ + GmacMcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacUcastHashFilter = 0x00000002, + GmacUcastHashFilterOn = 0x00000002, /* (HUC)Unicast Hash filtering only 1 RW */ + GmacUcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacPromiscuousMode = 0x00000001, + GmacPromiscuousModeOn = 0x00000001, /* Receive all frames 0 RW */ + GmacPromiscuousModeOff = 0x00000000, /* Receive filtered packets only 0 */ +}; + + +/*GmacGmiiAddr = 0x0010, GMII address Register(ext. Phy) Layout */ +enum GmacGmiiAddrReg { + GmiiDevMask = 0x0000F800, /* (PA)GMII device address 15:11 RW 0x00 */ + GmiiDevShift = 11, + + GmiiRegMask = 0x000007C0, /* (GR)GMII register in selected Phy 10:6 RW 0x00 */ + GmiiRegShift = 6, + + GmiiCsrClkMask = 0x0000001C, /*CSR Clock bit Mask 4:2 */ + GmiiCsrClk5 = 0x00000014, /* (CR)CSR Clock Range 250-300 MHz 4:2 RW 000 */ + GmiiCsrClk4 = 0x00000010, /* 150-250 MHz */ + GmiiCsrClk3 = 0x0000000C, /* 35-60 MHz */ + GmiiCsrClk2 = 0x00000008, /* 20-35 MHz */ + GmiiCsrClk1 = 0x00000004, /* 100-150 MHz */ + GmiiCsrClk0 = 0x00000000, /* 60-100 MHz */ + + GmiiWrite = 0x00000002, /* (GW)Write to register 1 RW */ + GmiiRead = 0x00000000, /* Read from register 0 */ + + GmiiBusy = 0x00000001, /* (GB)GMII interface is busy 0 RW 0 */ +}; + +enum GmacVlanTagReg { + GmacEnableSVlan = 0x00040000, /* (ESVL) Enabe S-Vlan */ + GmacVlanInvMatch = 0x00020000, /* (VTIM) VLAN tag inverse match enable */ + GmacEnable12BitComp = 0x00010000, /* (ETV) Enable 12-bit VLAN tag comparision */ + GmacVlanTagMsk = 0x0000FFFF /* (VL) VLAN tag */ + +}; + + +enum GmacLPICtrlStsReg { + GmacLPITxAuto = 0x00080000, + GmacLPIPhyStsEn = 0x00040000, + GmacLPIPhySts = 0x00020000, + GmacLPIEn = 0x00010000, + GmacRxLPISts = 0x00000200, + GmacTxLPISts = 0x00000100, + GmacRxLPIExit = 0x00000008, + GmacRxLPIEnter = 0x00000004, + GmacTxLPIExit = 0x00000002, + GmacTxLPIEnter = 0x00000001, +}; + +enum GmacLPITimerCtrlReg { + GmacLPILinkStableTimerMsk = 0x03FF0000, + GmacLPITxWaitTimerMsk = 0x0000FFFF, +}; + + +/* GmacGmiiData = 0x0014, GMII data Register(ext. Phy) Layout */ +enum GmacGmiiDataReg { + GmiiDataMask = 0x0000FFFF, /* (GD)GMII Data 15:0 RW 0x0000 */ +}; + + +/*GmacFlowControl = 0x0018, Flow control Register Layout */ +enum GmacFlowControlReg { + GmacPauseTimeMask = 0xFFFF0000, /* (PT) PAUSE TIME field in the control frame 31:16 RW 0x0000 */ + GmacPauseTimeShift = 16, + + GmacPauseLowThresh = 0x00000030, + GmacPauseLowThresh3 = 0x00000030, /* (PLT)thresh for pause tmr 256 slot time 5:4 RW */ + GmacPauseLowThresh2 = 0x00000020, /* 144 slot time */ + GmacPauseLowThresh1 = 0x00000010, /* 28 slot time */ + GmacPauseLowThresh0 = 0x00000000, /* 4 slot time 000 */ + + GmacUnicastPauseFrame = 0x00000008, + GmacUnicastPauseFrameOn = 0x00000008, /* (UP)Detect pause frame with unicast addr. 3 RW */ + GmacUnicastPauseFrameOff = 0x00000000, /* Detect only pause frame with multicast addr. 0 */ + + GmacRxFlowControl = 0x00000004, + GmacRxFlowControlEnable = 0x00000004, /* (RFE)Enable Rx flow control 2 RW */ + GmacRxFlowControlDisable = 0x00000000, /* Disable Rx flow control 0 */ + + GmacTxFlowControl = 0x00000002, + GmacTxFlowControlEnable = 0x00000002, /* (TFE)Enable Tx flow control 1 RW */ + GmacTxFlowControlDisable = 0x00000000, /* Disable flow control 0 */ + + GmacFlowControlBackPressure= 0x00000001, + GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */ +}; + + +enum GmacVLANIncRepReg { + GmacSVLAN = 0x00080000, + GmacCVLAN = 0x00000000, + GmacVLP = 0x00040000, + GmacVLANNoACT = 0x00000000, + GmacVLANDel = 0x00010000, + GmacVLANIns = 0x00020000, + GmacVLANRep = 0x00030000, + GmacVLANMsk = 0x0000FFFF + +}; + +/* GmacInterruptStatus = 0x0038, Mac Interrupt ststus register */ +enum GmacInterruptStatusBitDefinition { + GmacLPIIntSts = 0x00000400, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/ + GmacTSIntSts = 0x00000200, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/ + GmacMmcRxChksumOffload = 0x00000080, /* set if int generated in MMC RX CHECKSUM OFFLOAD int register */ + GmacMmcTxIntSts = 0x00000040, /* set if int generated in MMC TX Int register */ + GmacMmcRxIntSts = 0x00000020, /* set if int generated in MMC RX Int register */ + GmacMmcIntSts = 0x00000010, /* set if any of the above bit [7:5] is set */ + GmacPmtIntSts = 0x00000008, /* set whenver magic pkt/wake-on-lan frame is received */ + GmacPcsAnComplete = 0x00000004, /* set when AN is complete in TBI/RTBI/SGMIII phy interface */ + GmacPcsLnkStsChange = 0x00000002, /* set if any lnk status change in TBI/RTBI/SGMII interface */ + GmacRgmiiIntSts = 0x00000001, /* set if any change in lnk status of RGMII interface */ + +}; + +/* GmacInterruptMask = 0x003C, Mac Interrupt Mask register */ +enum GmacInterruptMaskBitDefinition { + GmacTSIntMask = 0x00000200, /* when set disables the time stamp interrupt generation */ + GmacPmtIntMask = 0x00000008, /* when set Disables the assertion of PMT interrupt */ + GmacPcsAnIntMask = 0x00000004, /* When set disables the assertion of PCS AN complete interrupt */ + GmacPcsLnkStsIntMask = 0x00000002, /* when set disables the assertion of PCS lnk status change interrupt */ + GmacRgmiiIntMask = 0x00000001, /* when set disables the assertion of RGMII int */ +}; + +/********************************************************** + * GMAC DMA registers + * For Pci based system address is BARx + GmaDmaBase + * For any other system translation is done accordingly + **********************************************************/ + +enum DmaRegisters { + DmaBusMode = 0x0000, /* CSR0 - Bus Mode Register */ + DmaTxPollDemand = 0x0004, /* CSR1 - Transmit Poll Demand Register */ + DmaRxPollDemand = 0x0008, /* CSR2 - Receive Poll Demand Register */ + DmaRxBaseAddr = 0x000C, /* CSR3 - Receive Descriptor list base address */ + DmaTxBaseAddr = 0x0010, /* CSR4 - Transmit Descriptor list base address */ + DmaStatus = 0x0014, /* CSR5 - Dma status Register */ + DmaControl = 0x0018, /* CSR6 - Dma Operation Mode Register */ + DmaInterrupt = 0x001C, /* CSR7 - Interrupt enable */ + DmaMissedFr = 0x0020, /* CSR8 - Missed Frame & Buffer overflow Counter */ + DmaTxCurrDesc = 0x0048, /* - Current host Tx Desc Register */ + DmaRxCurrDesc = 0x004C, /* - Current host Rx Desc Register */ + DmaTxCurrAddr = 0x0050, /* CSR20 - Current host transmit buffer address */ + DmaRxCurrAddr = 0x0054, /* CSR21 - Current host receive buffer address */ + + +}; + +/********************************************************** + * DMA Engine registers Layout + **********************************************************/ + +/*DmaBusMode = 0x0000, CSR0 - Bus Mode */ +enum DmaBusModeReg { + /* Bit description Bits R/W Reset value */ + + DmaFixedBurstEnable = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, INCR8 or INCR16 16 RW */ + DmaFixedBurstDisable = 0x00000000, /* SINGLE, INCR 0 */ + + DmaTxPriorityRatio11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 15:14 RW 00 */ + DmaTxPriorityRatio21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */ + DmaTxPriorityRatio31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */ + DmaTxPriorityRatio41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */ + + DmaBurstLengthx8 = 0x01000000, /* When set mutiplies the PBL by 8 24 RW 0 */ + + DmaBurstLength256 = 0x01002000, /*(DmaBurstLengthx8 | DmaBurstLength32) = 256 [24]:13:8 */ + DmaBurstLength128 = 0x01001000, /*(DmaBurstLengthx8 | DmaBurstLength16) = 128 [24]:13:8 */ + DmaBurstLength64 = 0x01000800, /*(DmaBurstLengthx8 | DmaBurstLength8) = 64 [24]:13:8 */ + DmaBurstLength32 = 0x00002000, /* (PBL) programmable Dma burst length = 32 13:8 RW */ + DmaBurstLength16 = 0x00001000, /* Dma burst length = 16 */ + DmaBurstLength8 = 0x00000800, /* Dma burst length = 8 */ + DmaBurstLength4 = 0x00000400, /* Dma burst length = 4 */ + DmaBurstLength2 = 0x00000200, /* Dma burst length = 2 */ + DmaBurstLength1 = 0x00000100, /* Dma burst length = 1 */ + DmaBurstLength0 = 0x00000000, /* Dma burst length = 0 0x00 */ + + DmaDescriptor8Words = 0x00000080, /* Enh Descriptor works 1=> 8 word descriptor 7 0 */ + DmaDescriptor4Words = 0x00000000, /* Enh Descriptor works 0=> 4 word descriptor 7 0 */ + + DmaDescriptorSkip16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) 6:2 RW */ + DmaDescriptorSkip8 = 0x00000020, /* between two unchained descriptors */ + DmaDescriptorSkip4 = 0x00000010, /* */ + DmaDescriptorSkip2 = 0x00000008, /* */ + DmaDescriptorSkip1 = 0x00000004, /* */ + DmaDescriptorSkip0 = 0x00000000, /* 0x00 */ + + DmaArbitRr = 0x00000000, /* (DA) DMA RR arbitration 1 RW 0 */ + DmaArbitPr = 0x00000002, /* Rx has priority over Tx */ + + DmaResetOn = 0x00000001, /* (SWR)Software Reset DMA engine 0 RW */ + DmaResetOff = 0x00000000, /* 0 */ +}; + + +/*DmaStatus = 0x0014, CSR5 - Dma status Register */ +enum DmaStatusReg { + /*Bit 28 27 and 26 indicate whether the interrupt due to PMT GMACMMC or GMAC LINE Remaining bits are DMA interrupts*/ + + + GmacLPIIntr = 0x40000000, /* GMC LPI interrupt 31 RO 0 */ + + + GmacPmtIntr = 0x10000000, /* (GPI)Gmac subsystem interrupt 28 RO 0 */ + GmacMmcIntr = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt 27 RO 0 */ + GmacLineIntfIntr = 0x04000000, /* Line interface interrupt 26 RO 0 */ + + DmaErrorBit2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc. access 25 RO 0 */ + DmaErrorBit1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfr 24 RO 0 */ + DmaErrorBit0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA 23 RO 0 */ + + DmaTxState = 0x00700000, /* (TS)Transmit process state 22:20 RO */ + DmaTxStopped = 0x00000000, /* Stopped - Reset or Stop Tx Command issued 000 */ + DmaTxFetching = 0x00100000, /* Running - fetching the Tx descriptor */ + DmaTxWaiting = 0x00200000, /* Running - waiting for status */ + DmaTxReading = 0x00300000, /* Running - reading the data from host memory */ + DmaTxSuspended = 0x00600000, /* Suspended - Tx Descriptor unavailabe */ + DmaTxClosing = 0x00700000, /* Running - closing Rx descriptor */ + + DmaRxState = 0x000E0000, /* (RS)Receive process state 19:17 RO */ + DmaRxStopped = 0x00000000, /* Stopped - Reset or Stop Rx Command issued 000 */ + DmaRxFetching = 0x00020000, /* Running - fetching the Rx descriptor */ + DmaRxWaiting = 0x00060000, /* Running - waiting for packet */ + DmaRxSuspended = 0x00080000, /* Suspended - Rx Descriptor unavailable */ + DmaRxClosing = 0x000A0000, /* Running - closing descriptor */ + DmaRxQueuing = 0x000E0000, /* Running - queuing the recieve frame into host memory */ + + DmaIntNormal = 0x00010000, /* (NIS)Normal interrupt summary 16 RW 0 */ + DmaIntAbnormal = 0x00008000, /* (AIS)Abnormal interrupt summary 15 RW 0 */ + + DmaIntEarlyRx = 0x00004000, /* Early receive interrupt (Normal) RW 0 */ + DmaIntBusError = 0x00002000, /* Fatal bus error (Abnormal) RW 0 */ + DmaIntEarlyTx = 0x00000400, /* Early transmit interrupt (Abnormal) RW 0 */ + DmaIntRxWdogTO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) RW 0 */ + DmaIntRxStopped = 0x00000100, /* Receive process stopped (Abnormal) RW 0 */ + DmaIntRxNoBuffer = 0x00000080, /* Receive buffer unavailable (Abnormal) RW 0 */ + DmaIntRxCompleted = 0x00000040, /* Completion of frame reception (Normal) RW 0 */ + DmaIntTxUnderflow = 0x00000020, /* Transmit underflow (Abnormal) RW 0 */ + DmaIntRcvOverflow = 0x00000010, /* Receive Buffer overflow interrupt RW 0 */ + DmaIntTxJabberTO = 0x00000008, /* Transmit Jabber Timeout (Abnormal) RW 0 */ + DmaIntTxNoBuffer = 0x00000004, /* Transmit buffer unavailable (Normal) RW 0 */ + DmaIntTxStopped = 0x00000002, /* Transmit process stopped (Abnormal) RW 0 */ + DmaIntTxCompleted = 0x00000001, /* Transmit completed (Normal) RW 0 */ +}; + +/*DmaControl = 0x0018, CSR6 - Dma Operation Mode Register */ +enum DmaControlReg { + DmaDisableDropTcpCs = 0x04000000, /* (DT) Dis. drop. of tcp/ip CS error frames 26 RW 0 */ + + DmaStoreAndForward = 0x00200000, /* (SF)Store and forward 21 RW 0 */ + DmaFlushTxFifo = 0x00100000, /* (FTF)Tx FIFO controller is reset to default 20 RW 0 */ + + DmaTxThreshCtrl = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16:14 RW */ + DmaTxThreshCtrl16 = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16 16:14 RW */ + DmaTxThreshCtrl24 = 0x00018000, /* (TTC)Controls thre Threh of MTL tx Fifo 24 16:14 RW */ + DmaTxThreshCtrl32 = 0x00014000, /* (TTC)Controls thre Threh of MTL tx Fifo 32 16:14 RW */ + DmaTxThreshCtrl40 = 0x00010000, /* (TTC)Controls thre Threh of MTL tx Fifo 40 16:14 RW */ + DmaTxThreshCtrl256 = 0x0000c000, /* (TTC)Controls thre Threh of MTL tx Fifo 256 16:14 RW */ + DmaTxThreshCtrl192 = 0x00008000, /* (TTC)Controls thre Threh of MTL tx Fifo 192 16:14 RW */ + DmaTxThreshCtrl128 = 0x00004000, /* (TTC)Controls thre Threh of MTL tx Fifo 128 16:14 RW */ + DmaTxThreshCtrl64 = 0x00000000, /* (TTC)Controls thre Threh of MTL tx Fifo 64 16:14 RW 000 */ + + DmaTxStart = 0x00002000, /* (ST)Start/Stop transmission 13 RW 0 */ + + DmaRxFlowCtrlDeact = 0x00401800, /* (RFD)Rx flow control deact. threhold [22]:12:11 RW */ + DmaRxFlowCtrlDeact1K = 0x00000000, /* (RFD)Rx flow control deact. threhold (1kbytes) [22]:12:11 RW 00 */ + DmaRxFlowCtrlDeact2K = 0x00000800, /* (RFD)Rx flow control deact. threhold (2kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact3K = 0x00001000, /* (RFD)Rx flow control deact. threhold (3kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact4K = 0x00001800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact5K = 0x00400000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact6K = 0x00400800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact7K = 0x00401000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + + DmaRxFlowCtrlAct = 0x00800600, /* (RFA)Rx flow control Act. threhold [23]:10:09 RW */ + DmaRxFlowCtrlAct1K = 0x00000000, /* (RFA)Rx flow control Act. threhold (1kbytes) [23]:10:09 RW 00 */ + DmaRxFlowCtrlAct2K = 0x00000200, /* (RFA)Rx flow control Act. threhold (2kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct3K = 0x00000400, /* (RFA)Rx flow control Act. threhold (3kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct4K = 0x00000300, /* (RFA)Rx flow control Act. threhold (4kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct5K = 0x00800000, /* (RFA)Rx flow control Act. threhold (5kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct6K = 0x00800200, /* (RFA)Rx flow control Act. threhold (6kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct7K = 0x00800400, /* (RFA)Rx flow control Act. threhold (7kbytes) [23]:10:09 RW */ + + DmaRxThreshCtrl = 0x00000018, /* (RTC)Controls thre Threh of MTL rx Fifo 4:3 RW */ + DmaRxThreshCtrl64 = 0x00000000, /* (RTC)Controls thre Threh of MTL tx Fifo 64 4:3 RW */ + DmaRxThreshCtrl32 = 0x00000008, /* (RTC)Controls thre Threh of MTL tx Fifo 32 4:3 RW */ + DmaRxThreshCtrl96 = 0x00000010, /* (RTC)Controls thre Threh of MTL tx Fifo 96 4:3 RW */ + DmaRxThreshCtrl128 = 0x00000018, /* (RTC)Controls thre Threh of MTL tx Fifo 128 4:3 RW */ + + DmaEnHwFlowCtrl = 0x00000100, /* (EFC)Enable HW flow control 8 RW */ + DmaDisHwFlowCtrl = 0x00000000, /* Disable HW flow control 0 */ + + DmaFwdErrorFrames = 0x00000080, /* (FEF)Forward error frames 7 RW 0 */ + DmaFwdUnderSzFrames = 0x00000040, /* (FUF)Forward undersize frames 6 RW 0 */ + DmaTxSecondFrame = 0x00000004, /* (OSF)Operate on second frame 4 RW 0 */ + DmaRxStart = 0x00000002, /* (SR)Start/Stop reception 1 RW 0 */ +}; + + +/*DmaInterrupt = 0x001C, CSR7 - Interrupt enable Register Layout */ +enum DmaInterruptReg { + DmaIeNormal = DmaIntNormal , /* Normal interrupt enable RW 0 */ + DmaIeAbnormal = DmaIntAbnormal , /* Abnormal interrupt enable RW 0 */ + + DmaIeEarlyRx = DmaIntEarlyRx , /* Early receive interrupt enable RW 0 */ + DmaIeBusError = DmaIntBusError , /* Fatal bus error enable RW 0 */ + DmaIeEarlyTx = DmaIntEarlyTx , /* Early transmit interrupt enable RW 0 */ + DmaIeRxWdogTO = DmaIntRxWdogTO , /* Receive Watchdog Timeout enable RW 0 */ + DmaIeRxStopped = DmaIntRxStopped , /* Receive process stopped enable RW 0 */ + DmaIeRxNoBuffer = DmaIntRxNoBuffer , /* Receive buffer unavailable enable RW 0 */ + DmaIeRxCompleted = DmaIntRxCompleted, /* Completion of frame reception enable RW 0 */ + DmaIeTxUnderflow = DmaIntTxUnderflow, /* Transmit underflow enable RW 0 */ + + DmaIeRxOverflow = DmaIntRcvOverflow, /* Receive Buffer overflow interrupt RW 0 */ + DmaIeTxJabberTO = DmaIntTxJabberTO , /* Transmit Jabber Timeout enable RW 0 */ + DmaIeTxNoBuffer = DmaIntTxNoBuffer , /* Transmit buffer unavailable enable RW 0 */ + DmaIeTxStopped = DmaIntTxStopped , /* Transmit process stopped enable RW 0 */ + DmaIeTxCompleted = DmaIntTxCompleted, /* Transmit completed enable RW 0 */ +}; + + +/********************************************************** + * DMA Engine descriptors + **********************************************************/ + +/* +**********Enhanced Descritpor structure to support 8K buffer per buffer **************************** + +DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address +DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + +Similarly +DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address +DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + -------------------------------------------------------------------------- + RDES0 |OWN (31)| Status | + -------------------------------------------------------------------------- + RDES1 | Ctrl | Res | Byte Count Buffer 2 | Ctrl | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + RDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + RDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + + -------------------------------------------------------------------------- + TDES0 |OWN (31)| Ctrl | Res | Ctrl | Res | Status | + -------------------------------------------------------------------------- + TDES1 | Res | Byte Count Buffer 2 | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + TDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + TDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + +*/ + +enum DmaDescriptorStatus /* status word of DMA descriptor */ +{ + + DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */ + + DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */ + + DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */ + DescFrameLengthShift = 16, + + DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */ + /* DE || OE || IPC || LC || RWT || RE || CE */ + DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */ + DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */ + DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */ + DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */ + DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */ + DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */ + DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */ + DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */ + DescRxTSAvailable = 0x00000080, /* Share bit with (Giant Frame)Rx 7 */ + DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */ + DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */ + DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */ + DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */ + DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */ +// DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */ + + DescRxEXTsts = 0x00000001, /* Extended Status Available (RDES4) 0 */ + + DescTxIntEnable = 0x40000000, /* (IC)Tx - interrupt on completion 30 */ + DescTxLast = 0x20000000, /* (LS)Tx - Last segment of the frame 29 */ + DescTxFirst = 0x10000000, /* (FS)Tx - First segment of the frame 28 */ + DescTxDisableCrc = 0x08000000, /* (DC)Tx - Add CRC disabled (first segment only) 27 */ + DescTxDisablePadd = 0x04000000, /* (DP)disable padding, added by - reyaz 26 */ + DescTxTSEnable = 0x02000000, /* (TTSE) Transmit Timestamp Enable 25 */ + DescTxCrcReplacement = 0x01000000, /* (CRCR) CRC Replacement Control 24 */ + DescTxCisMask = 0x00c00000, /* Tx checksum offloading control mask 23:22 */ + DescTxCisBypass = 0x00000000, /* Checksum bypass */ + DescTxCisIpv4HdrCs = 0x00400000, /* IPv4 header checksum */ + DescTxCisTcpOnlyCs = 0x00800000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */ + DescTxCisTcpPseudoCs = 0x00c00000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */ + + TxDescEndOfRing = 0x00200000, /* (TER)End of descriptors ring 21 */ + TxDescChain = 0x00100000, /* (TCH)Second buffer address is chain address 20 */ + + DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */ + DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */ + DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + + DescRxTSavail = 0x00000080, /* Time stamp available 7 */ + DescRxFrameType = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescTxTSStatus = 0x00020000, /* (TTSS) Transmit Timestamp Status 17 */ + DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */ + DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */ + DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */ + DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */ + DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */ + DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */ + DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */ + DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */ + DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */ + + DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */ + DescTxCollShift = 3, + + DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */ + DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */ + DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */ + + /* + This explains the RDES1/TDES1 bits layout + -------------------------------------------------------------------- + RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 | + -------------------------------------------------------------------- + + */ +// DmaDescriptorLength length word of DMA descriptor + + + RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */ + RxDescEndOfRing = 0x00008000, /* (TER)End of descriptors ring 15 */ + RxDescChain = 0x00004000, /* (TCH)Second buffer address is chain address 14 */ + + + DescSize2Mask = 0x1FFF0000, /* (TBS2) Buffer 2 size 28:16 */ + DescSize2Shift = 16, + DescSize1Mask = 0x00001FFF, /* (TBS1) Buffer 1 size 12:0 */ + DescSize1Shift = 0, + + + /* + This explains the RDES4 Extended Status bits layout + -------------------------------------------------------------------- + RDES4 | Extended Status | + -------------------------------------------------------------------- + */ + + DescRxPtpAvail = 0x00004000, /* PTP snapshot available 14 */ + DescRxPtpVer = 0x00002000, /* When set indicates IEEE1584 Version 2 (else Ver1) 13 */ + DescRxPtpFrameType = 0x00001000, /* PTP frame type Indicates PTP sent over ethernet 12 */ + DescRxPtpMessageType = 0x00000F00, /* Message Type 11:8 */ + DescRxPtpNo = 0x00000000, /* 0000 => No PTP message received */ + DescRxPtpSync = 0x00000100, /* 0001 => Sync (all clock types) received */ + DescRxPtpFollowUp = 0x00000200, /* 0010 => Follow_Up (all clock types) received */ + DescRxPtpDelayReq = 0x00000300, /* 0011 => Delay_Req (all clock types) received */ + DescRxPtpDelayResp = 0x00000400, /* 0100 => Delay_Resp (all clock types) received */ + DescRxPtpPdelayReq = 0x00000500, /* 0101 => Pdelay_Req (in P to P tras clk) or Announce in Ord and Bound clk */ + DescRxPtpPdelayResp = 0x00000600, /* 0110 => Pdealy_Resp(in P to P trans clk) or Management in Ord and Bound clk */ + DescRxPtpPdelayRespFP = 0x00000700, /* 0111 => Pdealy_Resp_Follow_Up (in P to P trans clk) or Signaling in Ord and Bound clk */ + DescRxPtpIPV6 = 0x00000080, /* Received Packet is in IPV6 Packet 7 */ + DescRxPtpIPV4 = 0x00000040, /* Received Packet is in IPV4 Packet 6 */ + + DescRxChkSumBypass = 0x00000020, /* When set indicates checksum offload engine 5 + is bypassed */ + DescRxIpPayloadError = 0x00000010, /* When set indicates 16bit IP payload CS is in error 4 */ + DescRxIpHeaderError = 0x00000008, /* When set indicates 16bit IPV4 header CS is in 3 + error or IP datagram version is not consistent + with Ethernet type value */ + DescRxIpPayloadType = 0x00000007, /* Indicate the type of payload encapsulated 2:0 + in IPdatagram processed by COE (Rx) */ + DescRxIpPayloadUnknown= 0x00000000, /* Unknown or didnot process IP payload */ + DescRxIpPayloadUDP = 0x00000001, /* UDP */ + DescRxIpPayloadTCP = 0x00000002, /* TCP */ + DescRxIpPayloadICMP = 0x00000003, /* ICMP */ + +}; + + +// Rx Descriptor COE type2 encoding +enum RxDescCOEEncode { + RxLenLT600 = 0, /* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600 */ + RxIpHdrPayLoadChkBypass = 1, /* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) */ + RxIpHdrPayLoadRes = 2, /* Bit(5:7:0)=>2 Reserved */ + RxChkBypass = 3, /* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed */ + RxNoChkError = 4, /* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected */ + RxPayLoadChkError = 5, /* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames */ + RxIpHdrChkError = 6, /* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames */ + RxIpHdrPayLoadChkError = 7, /* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames */ +}; + +/********************************************************** + * DMA engine interrupt handling functions + **********************************************************/ + +enum synopGMACDmaIntEnum /* Intrerrupt types */ +{ + synopGMACDmaRxNormal = 0x01, /* normal receiver interrupt */ + synopGMACDmaRxAbnormal = 0x02, /* abnormal receiver interrupt */ + synopGMACDmaRxStopped = 0x04, /* receiver stopped */ + synopGMACDmaTxNormal = 0x08, /* normal transmitter interrupt */ + synopGMACDmaTxAbnormal = 0x10, /* abnormal transmitter interrupt */ + synopGMACDmaTxStopped = 0x20, /* transmitter stopped */ + synopGMACDmaError = 0x80, /* Dma engine error */ + +}; + + +/********************************************************** + * Initial register values + **********************************************************/ +enum InitialRegisters { + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode */ + // CHANGED: Pass control config, dest addr filter normal, added source address filter, multicast & unicast + // Hash filter. + /* = GmacFilterOff | GmacPassControlOff | GmacBroadcastEnable */ + GmacFrameFilterInitFdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacPromiscuousModeOff | GmacUcastHashFilterOff, + + /* Full-duplex mode */ + GmacFlowControlInitFdx = GmacUnicastPauseFrameOff | GmacRxFlowControlEnable | GmacTxFlowControlEnable, + + /* Full-duplex mode */ + GmacGmiiAddrInitFdx = GmiiCsrClk2, + + + /* Half-duplex mode with perfect filter on */ + // CHANGED: Removed Endian configuration, added single bit config for PAD/CRC strip, + /*| GmacSelectMii | GmacLittleEndian | GmacDisableRxOwn | GmacLoopbackOff*/ + GmacConfigInitHdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode with perfect filter on */ + GmacConfigInitHdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode */ + GmacFrameFilterInitHdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacUcastHashFilterOff| GmacPromiscuousModeOff, + + /* Half-duplex mode */ + GmacFlowControlInitHdx = GmacUnicastPauseFrameOff | GmacRxFlowControlDisable | GmacTxFlowControlDisable, + + /* Half-duplex mode */ + GmacGmiiAddrInitHdx = GmiiCsrClk2, + + + + /********************************************** + *DMA configurations + **********************************************/ + + DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip2 | DmaResetOff, +// DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip4 | DmaResetOff, + + /* 1000 Mb/s mode */ + DmaControlInit1000 = DmaStoreAndForward,// | DmaTxSecondFrame , + + /* 100 Mb/s mode */ + DmaControlInit100 = DmaStoreAndForward, + + /* 10 Mb/s mode */ + DmaControlInit10 = DmaStoreAndForward, + + /* Interrupt groups */ + DmaIntErrorMask = DmaIntBusError, /* Error */ + DmaIntRxAbnMask = DmaIntRxNoBuffer, /* receiver abnormal interrupt */ + DmaIntRxNormMask = DmaIntRxCompleted, /* receiver normal interrupt */ + DmaIntRxStoppedMask = DmaIntRxStopped, /* receiver stopped */ + DmaIntTxAbnMask = DmaIntTxUnderflow, /* transmitter abnormal interrupt */ + DmaIntTxNormMask = DmaIntTxCompleted, /* transmitter normal interrupt */ + DmaIntTxStoppedMask = DmaIntTxStopped, /* transmitter stopped */ + + DmaIntEnable = DmaIeNormal | DmaIeAbnormal | DmaIntErrorMask + | DmaIntRxAbnMask | DmaIntRxNormMask | DmaIntRxStoppedMask + | DmaIntTxAbnMask | DmaIntTxNormMask | DmaIntTxStoppedMask, + DmaIntDisable = 0, +}; + + + + +/********************************************************** + * Power Management (PMT) Block + **********************************************************/ + +/** + * PMT supports the reception of network (remote) wake-up frames and Magic packet frames. + * It generates interrupts for wake-up frames and Magic packets received by GMAC. + * PMT sits in Rx path and is enabled with remote wake-up frame enable and Magic packet enable. + * These enable are in PMT control and Status register and are programmed by apllication. + * + * When power down mode is enabled in PMT, all rx frames are dropped by the core. Core comes + * out of power down mode only when either Magic packe tor a Remote wake-up frame is received + * and the corresponding detection is enabled. + * + * Driver need not be modified to support this feature. Only Api to put the device in to power + * down mode is sufficient + */ + +#define WAKEUP_REG_LENGTH 8 /*This is the reg length for wake up register configuration*/ + +enum GmacPmtCtrlStatusBitDefinition { + GmacPmtFrmFilterPtrReset = 0x80000000, /* when set remote wake-up frame filter register pointer to 3'b000 */ + GmacPmtGlobalUnicast = 0x00000200, /* When set enables any unicast packet to be a wake-up frame */ + GmacPmtWakeupFrameReceived = 0x00000040, /* Wake up frame received */ + GmacPmtMagicPktReceived = 0x00000020, /* Magic Packet received */ + GmacPmtWakeupFrameEnable = 0x00000004, /* Wake-up frame enable */ + GmacPmtMagicPktEnable = 0x00000002, /* Magic packet enable */ + GmacPmtPowerDown = 0x00000001, /* Power Down */ +}; + + + + +/********************************************************** + * IEEE 1588-2008 Precision Time Protocol (PTP) Support + **********************************************************/ +enum PTPMessageType { + SYNC = 0x0, + Delay_Req = 0x1, + Pdelay_Req = 0x2, + Pdelay_Resp = 0x3, + Follow_up = 0x8, + Delay_Resp = 0x9, + Pdelay_Resp_Follow_Up = 0xA, + Announce = 0xB, + Signaling = 0xC, + Management = 0xD, +}; + + + +typedef struct TimeStampStruct { + u32 TSversion; /* PTP Version 1 or PTP version2 */ + u32 TSmessagetype; /* Message type associated with this time stamp */ + + u16 TShighest16; /* Highest 16 bit time stamp value, Valid onley when ADV_TIME_HIGH_WORD configured in corekit */ + u32 TSupper32; /* Most significant 32 bit time stamp value */ + u32 TSlower32; /* Least Significat 32 bit time stamp value */ + +} TimeStamp; + + +/** + * IEEE 1588-2008 is the optional module to support Ethernet frame time stamping. + * Sixty four (+16) bit time stamps are given in each frames transmit and receive status. + * The driver assumes the following + * 1. "IEEE 1588 Time Stamping" "TIME_STAMPING"is ENABLED in corekit + * 2. "IEEE 1588 External Time Stamp Input Enable" "EXT_TIME_STAMPING" is DISABLED in corekit + * 3. "IEEE 1588 Advanced Time Stamp support" "ADV_TIME_STAMPING" is ENABLED in corekit + * 4. "IEEE 1588 Higher Word Register Enable" "ADV_TIME_HIGH_WORD" is ENABLED in corekit + */ + +/* GmacTSControl = 0x0700, Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ +enum GmacTSControlReg { + GmacTSENMACADDR = 0x00040000, /* Enable Mac Addr for PTP filtering 18 RW 0 */ + + GmacTSCLKTYPE = 0x00030000, /* Select the type of clock node 17:16 RW 00 */ + /* + TSCLKTYPE TSMSTRENA TSEVNTENA Messages for wihich TS snapshot is taken + 00/01 X 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 00/01 1 0 DELAY_REQ + 00/01 0 1 SYNC + 10 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 10 NA 1 SYNC, FOLLOW_UP + 11 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP, PDELAY_REQ, PDELAY_RESP + 11 NA 1 SYNC, PDELAY_REQ, PDELAY_RESP + */ + GmacTSOrdClk = 0x00000000, /* 00=> Ordinary clock*/ + GmacTSBouClk = 0x00010000, /* 01=> Boundary clock*/ + GmacTSEtoEClk = 0x00020000, /* 10=> End-to-End transparent clock*/ + GmacTSPtoPClk = 0x00030000, /* 11=> P-to-P transparent clock*/ + + GmacTSMSTRENA = 0x00008000, /* Ena TS Snapshot for Master Messages 15 RW 0 */ + GmacTSEVNTENA = 0x00004000, /* Ena TS Snapshot for Event Messages 14 RW 0 */ + GmacTSIPV4ENA = 0x00002000, /* Ena TS snapshot for IPv4 13 RW 1 */ + GmacTSIPV6ENA = 0x00001000, /* Ena TS snapshot for IPv6 12 RW 0 */ + GmacTSIPENA = 0x00000800, /* Ena TS snapshot for PTP over E'net 11 RW 0 */ + GmacTSVER2ENA = 0x00000400, /* Ena PTP snooping for version 2 10 RW 0 */ + + GmacTSCTRLSSR = 0x00000200, /* Digital or Binary Rollover 9 RW 0 */ + + GmacTSENALL = 0x00000100, /* Enable TS fro all frames (Ver2 only) 8 RW 0 */ + + GmacTSADDREG = 0x00000020, /* Addend Register Update 5 RW_SC 0 */ + GmacTSUPDT = 0x00000008, /* Time Stamp Update 3 RW_SC 0 */ + GmacTSINT = 0x00000004, /* Time Atamp Initialize 2 RW_SC 0 */ + + GmacTSTRIG = 0x00000010, /* Time stamp interrupt Trigger Enable 4 RW_SC 0 */ + + GmacTSCFUPDT = 0x00000002, /* Time Stamp Fine/Coarse 1 RW 0 */ + GmacTSCUPDTCoarse = 0x00000000, /* 0=> Time Stamp update method is coarse */ + GmacTSCUPDTFine = 0x00000002, /* 1=> Time Stamp update method is fine */ + + GmacTSENA = 0x00000001, /* Time Stamp Enable 0 RW 0 */ +}; + + +/* GmacTSSubSecIncr = 0x0704, 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSSubSecIncrReg { + GmacSSINCMsk = 0x000000FF, /* Only Lower 8 bits are valid bits 7:0 RW 00 */ +}; + +/* GmacTSLow = 0x070C, Indicates whether the timestamp low count is positive or negative; for Adv timestamp it is always zero */ +enum GmacTSSign { + GmacTSSign = 0x80000000, /* PSNT 31 RW 0 */ + GmacTSPositive = 0x00000000, + GmacTSNegative = 0x80000000, +}; + +/*GmacTargetTimeLow = 0x0718, 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSLowReg { + GmacTSDecThr = 0x3B9AC9FF, /*when TSCTRLSSR is set the max value for GmacTargetTimeLowReg and GmacTimeStampLow register is 0x3B9AC9FF at 1ns precision */ +}; + +/* GmacTSHighWord = 0x0724, Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ +enum GmacTSHighWordReg { + GmacTSHighWordMask = 0x0000FFFF, /* Time Stamp Higher work register has only lower 16 bits valid */ +}; +/*GmacTSStatus = 0x0728, Time Stamp Status Register */ +enum GmacTSStatusReg { + GmacTSTargTimeReached = 0x00000002, /* Time Stamp Target Time Reached 1 RO 0 */ + GmacTSSecondsOverflow = 0x00000001, /* Time Stamp Seconds Overflow 0 RO 0 */ +}; + + +/********************************************************** + * Time stamp related functions + **********************************************************/ +void synopGMAC_TS_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev); +void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type); +void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value); +s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); +s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); + +void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled +void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled + +void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_val); // Update should happen making use of subsecond mask +void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val, + u32 * sec_val, u32 * sub_sec_val); // Reads the timestamp low,high and higher(Ver2) registers in the the struct pointer; readonly contents +void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val); //Loads the timestamp target register with the values provided + +void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val); +void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val); +void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val); //Read the target time stamp register contents + + +/********************************************************** + * Common functions + **********************************************************/ +s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val); +u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev); +s32 synopGMAC_read_phy_reg(u32 *RegBase,u32 PhyBase, u32 RegOffset, u16 * data); +s32 synopGMAC_write_phy_reg(u32 *RegBase, u32 PhyBase, u32 RegOffset, u16 data); +s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback); +s32 synopGMAC_read_version (synopGMACdevice * gmacdev) ; +s32 synopGMAC_reset (synopGMACdevice * gmacdev ); +s32 synopGMAC_reset_nocheck (synopGMACdevice * gmacdev ); +s32 synopGMAC_dma_bus_mode_init(synopGMACdevice * gmacdev, u32 init_value ); +s32 synopGMAC_dma_control_init(synopGMACdevice * gmacdev, u32 init_value); +void synopGMAC_wd_enable(synopGMACdevice * gmacdev); +void synopGMAC_wd_disable(synopGMACdevice * gmacdev); +void synopGMAC_jab_enable(synopGMACdevice * gmacdev); +void synopGMAC_jab_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_disable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_enable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_disable(synopGMACdevice * gmacdev); +void synopGMAC_select_gmii(synopGMACdevice * gmacdev); +void synopGMAC_select_mii(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_disable(synopGMACdevice * gmacdev); +void synopGMAC_loopback_on(synopGMACdevice * gmacdev); +void synopGMAC_loopback_off(synopGMACdevice * gmacdev); +void synopGMAC_set_full_duplex(synopGMACdevice * gmacdev); +void synopGMAC_set_half_duplex(synopGMACdevice * gmacdev); +void synopGMAC_retry_enable(synopGMACdevice * gmacdev); +void synopGMAC_retry_disable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_enable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_disable(synopGMACdevice * gmacdev); +void synopGMAC_back_off_limit(synopGMACdevice * gmacdev, u32 value); +void synopGMAC_deferral_check_enable(synopGMACdevice * gmacdev); +void synopGMAC_deferral_check_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_write_hash_table_high(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_write_hash_table_low(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_hash_perfect_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_Hash_filter_only_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_inverse(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_normal(synopGMACdevice * gmacdev); +void synopGMAC_set_pass_control(synopGMACdevice * gmacdev,u32 passcontrol); +void synopGMAC_broadcast_enable(synopGMACdevice * gmacdev); +void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_enable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_activate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_tx_deactivate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_pause_control(synopGMACdevice *gmacdev); +s32 synopGMAC_mac_init(synopGMACdevice * gmacdev); +s32 synopGMAC_check_phy_init (synopGMACdevice * gmacdev); +s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr); +s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr); +s32 synopGMAC_attach (synopGMACdevice * gmacdev, u32 macBase, u32 dmaBase, u32 phyBase); +void synopGMAC_rx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_rx_desc_init_chain(DmaDesc * desc); +void synopGMAC_tx_desc_init_chain(DmaDesc * desc); +s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev); +void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_set_owner_dma(DmaDesc *desc); +void synopGMAC_set_desc_sof(DmaDesc *desc); +void synopGMAC_set_desc_eof(DmaDesc *desc); +bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_da_filter_failed(DmaDesc *desc); +bool synopGMAC_is_sa_filter_failed(DmaDesc *desc); +bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc); +u32 synopGMAC_get_rx_desc_frame_length(u32 status); +bool synopGMAC_is_desc_valid(u32 status); +bool synopGMAC_is_desc_empty(DmaDesc *desc); +bool synopGMAC_is_rx_desc_valid(u32 status); +bool synopGMAC_is_tx_aborted(u32 status); +bool synopGMAC_is_tx_carrier_error(u32 status); +u32 synopGMAC_get_tx_collision_count(u32 status); +u32 synopGMAC_is_exc_tx_collisions(u32 status); +bool synopGMAC_is_rx_frame_damaged(u32 status); +bool synopGMAC_is_rx_frame_collision(u32 status); +bool synopGMAC_is_rx_crc(u32 status); +bool synopGMAC_is_frame_dribbling_errors(u32 status); +bool synopGMAC_is_rx_frame_length_errors(u32 status); +bool synopGMAC_is_last_rx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_last_tx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_rx_desc_chained(DmaDesc * desc); +bool synopGMAC_is_tx_desc_chained(DmaDesc * desc); +void synopGMAC_get_desc_data(DmaDesc * desc, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1); + +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); + +s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 offload_needed, u32 ts); +s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1); + +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); + +void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev); +void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev); +void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership(DmaDesc * desc); +void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev); +/******Following APIs are valid only for Enhanced Descriptor from 3.50a release onwards*******/ +bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status); +bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status); +/*******************PMT APIs***************************************/ +void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_enable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_disable(synopGMACdevice *gmacdev); +void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev); +void synopGMAC_magic_packet_disable(synopGMACdevice *gmacdev); +void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev); +bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev); +bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev); +void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents); + +/*******************Ip checksum offloading APIs***************************************/ +void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_disable_rx_chksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev); +u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status); +void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc); + + +// For testing --ya +void synopGMAC_src_addr_insert_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_insert_disable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_replace_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_replace_disable(synopGMACdevice * gmacdev); + +void synopGMAC_svlan_insertion_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_cvlan_insertion_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_svlan_replace_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_cvlan_replace_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_vlan_deletion_enable(synopGMACdevice * gmacdev); +void synopGMAC_vlan_no_act_enable(synopGMACdevice * gmacdev); + +void synopGMAC_set_crc_replacement(synopGMACdevice * gmacdev); +void synopGMAC_clr_crc_replacement(synopGMACdevice * gmacdev); + +void synopGMAC_enable_under_size_pkt(synopGMACdevice * gmacdev); +void synopGMAC_disable_under_size_pkt(synopGMACdevice * gmacdev); + +void synopGMAC_enable_crc_err_pkt(synopGMACdevice * gmacdev); +void synopGMAC_disable_crc_err_pkt(synopGMACdevice * gmacdev); + +#endif /* End of file */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h new file mode 100644 index 000000000..0c95eee55 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h @@ -0,0 +1,63 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/** \file + * Header file for the nework dependent functionality. + * The function prototype listed here are linux dependent. + * + * \internal + * ---------------------------REVISION HISTORY------------------- + * Synopsys 01/Aug/2007 Created + */ +#include "synopGMAC_Dev.h" + + +#ifndef SYNOP_GMAC_NETWORK_INTERFACE_H +#define SYNOP_GMAC_NETWORK_INTERFACE_H 1 + +//#define EMULATION + +//#define TEST_RGMII +#define TEST_RMII + +//#define CACHE_ON + + +s32 synopGMAC_open(int intf); +s32 synopGMAC_open_selftest(int intf); +s32 synopGMAC_close(int intf); +s32 synopGMAC_xmit_frames(struct sk_buff *, int intf, u32 offload_needed, u32 ts); +void synopGMAC_set_multicast_list(int intf); +s32 synopGMAC_set_mac_address(int intf, u8*); +s32 synopGMAC_change_mtu(int intf,s32); +void synop_handle_transmit_over(int intf); +//void synop_handle_received_data(int intf); +s32 synop_handle_received_data(int intf, u8 **buf); // Chris, to get RX buffer pointer +void synopGMAC_set_mode(int intf, int mode); + +void synopGMAC_powerup_mac(synopGMACdevice *gmacdev); +void synopGMAC_powerdown_mac(synopGMACdevice *gmacdev); +s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode); +s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode); + + +#endif /* End of file */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h new file mode 100644 index 000000000..b3daf4a1e --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h @@ -0,0 +1,183 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/**\file + * This file serves as the wrapper for the platform/OS dependent functions + * It is needed to modify these functions accordingly based on the platform and the + * OS. Whenever the synopsys GMAC driver ported on to different platform, this file + * should be handled at most care. + * The corresponding function definitions for non-inline functions are available in + * synopGMAC_plat.c file. + * \internal + * -------------------------------------REVISION HISTORY--------------------------- + * Synopsys 01/Aug/2007 Created + */ + + +#ifndef SYNOP_GMAC_PLAT_H +#define SYNOP_GMAC_PLAT_H 1 + +#include +#include "NuMicro.h" + +#define TR0(fmt, args...) printf("SynopGMAC: " fmt, ##args) + +//#define DEBUG +#ifdef DEBUG +#undef TR +# define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args) +#else +# define TR(fmt, args...) /* not debugging: nothing */ +#endif + +typedef unsigned char u8; ///< Define 8-bit unsigned data type +typedef unsigned short u16; ///< Define 16-bit unsigned data type +typedef unsigned int u32; ///< Define 32-bit unsigned data type +typedef signed int s32; ///< Define 32-bit signed data type +//typedef unsigned long long u64; +typedef unsigned int u64; + + +typedef int bool; +enum synopGMAC_boolean { + false = 0, + true = 1 +}; + +#define DEFAULT_DELAY_VARIABLE 10 +#define DEFAULT_LOOP_VARIABLE 10000 + +/* There are platform related endian conversions + * + */ + +#define LE32_TO_CPU __le32_to_cpu +#define BE32_TO_CPU __be32_to_cpu +#define CPU_TO_LE32 __cpu_to_le32 + +/* Error Codes */ +#define ESYNOPGMACNOERR 0 +#define ESYNOPGMACNOMEM 1 +#define ESYNOPGMACPHYERR 2 +#define ESYNOPGMACBUSY 3 + + +/** + * These are the wrapper function prototypes for OS/platform related routines + */ + +extern void plat_delay(uint32_t ticks); + + +/** + * The Low level function to read register contents from Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * \return Returns the register contents + */ +static u32 __INLINE synopGMACReadReg(u32 *RegBase, u32 RegOffset) +{ + + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + return data; + +} + +/** + * The Low level function to write to a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Data to be written + * \return void + */ +static void __INLINE synopGMACWriteReg(u32 *RegBase, u32 RegOffset, u32 RegData) +{ + + u64 addr = (u64)RegBase + RegOffset; + if(RegOffset == 0) + plat_delay(1); + outp32((void *)addr, RegData); + return; +} + +/** + * The Low level function to set bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return void + */ +static void __INLINE synopGMACSetBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data |= BitPos; + + outp32((void *)addr, data); + + return; +} + + +/** + * The Low level function to clear bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to clear bits to logical 0 + * \return void + */ +static void __INLINE synopGMACClearBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data &= (~BitPos); + + outp32((void *)addr, data); + return; +} + +/** + * The Low level function to Check the setting of the bits. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return returns TRUE if set to '1' returns FALSE if set to '0'. Result undefined there are no bit set in the BitPos argument. + * + */ +static bool __INLINE synopGMACCheckBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data &= BitPos; + if(data) return true; + else return false; + +} + + +#endif diff --git a/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h b/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h index afcc82d87..fa8d61ee1 100644 --- a/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h +++ b/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h @@ -17,9 +17,18 @@ #define RFO_HP 2 /* STM32WL Nucleo antenna switch defines */ -#define RBI_CONF_RFO_LP_HP 0 -#define RBI_CONF_RFO_LP 1 -#define RBI_CONF_RFO_HP 2 +#define RBI_CONF_RFO_LP_HP 0 +#define RBI_CONF_RFO_LP 1 +#define RBI_CONF_RFO_HP 2 +// Some boards such as LoRa-E5 and RAK3172 have only RFO_HP path wired +// thus, in EU868 mode, TX peak is 80mA (over consumption) +// We made a fix that decrease consumption according datasheet but +// since fix breaks HW machting network, transmit range may be lowered so +// it's depending on what you want to achieve, hi range or low consumption +// Setting RBI_CONF_RFO_HP_LPFIX decrease power according datasheet but can +// reduce range (long ones) due to bad HW macthing network on the both modules +// See https://github.com/ARMmbed/mbed-os/pull/15017#issuecomment-1173455762 +#define RBI_CONF_RFO_HP_LPFIX 3 typedef enum { RBI_SWITCH_OFF = 0, diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h new file mode 100644 index 000000000..23625b5b6 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h @@ -0,0 +1,262 @@ +/** + * \file aes_alt.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_AES_ALT_H +#define MBEDTLS_AES_ALT_H + +#include "mbedtls/aes.h" + +#if defined(MBEDTLS_AES_ALT) +// Regular implementation +// +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES context structure + */ +typedef struct { + uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ + uint32_t iv[4]; /* IV for next block cipher */ + uint32_t keys[8]; /* Cipher key */ +} +mbedtls_aes_context; + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_DECRYPT_ALT) + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + + +#endif /* MBEDTLS_AES_ALT */ + +#endif /* aes_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h new file mode 100644 index 000000000..1c1345e4b --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h @@ -0,0 +1,318 @@ +/** + * \file ccm.h + * + * \brief This file provides an API for the CCM authenticated encryption + * mode for block ciphers. + * + * CCM combines Counter mode encryption with CBC-MAC authentication + * for 128-bit block ciphers. + * + * Input to CCM includes the following elements: + * + * + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + * + * Definition of CCM*: + * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks + * Integer representation is fixed most-significant-octet-first order and + * the representation of octets is most-significant-bit-first order. This is + * consistent with RFC 3610. + */ +/* + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (c) 2022, Nuvoton Technology Corporation + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CCM_ALT_H +#define MBEDTLS_CCM_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbed_toolchain.h" +#include "mbedtls/cipher.h" +#include "NuMicro.h" + +#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ +#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ +#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +// Regular implementation +// + +#define MAX_CCM_BUF 256 +#define CCM_PBLOCK_SIZE MAX_CCM_BUF + +/** + * \brief The CCM context-type definition. The CCM context is passed + * to the APIs called. + */ +typedef struct mbedtls_ccm_context +{ + MBED_ALIGN(4) uint8_t ccm_buf[MAX_CCM_BUF + 16]; /* 16 bytes for ctr0 in packer */ + MBED_ALIGN(4) uint8_t out_buf[MAX_CCM_BUF + 16]; /* 16 bytes for tag */ + MBED_ALIGN(4) uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */ + uint32_t keySize; + uint32_t keys[8]; /* Cipher key */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE CCM */ + +} +mbedtls_ccm_context; + +/** + * \brief This function initializes the specified CCM context, + * to make references valid, and prepare the context + * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). + * + * \param ctx The CCM context to initialize. This must not be \c NULL. + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); + +/** + * \brief This function initializes the CCM context set in the + * \p ctx parameter and sets the encryption key. + * + * \param ctx The CCM context to initialize. This must be an initialized + * context. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must not be \c NULL. + * \param keybits The key size in bits. This must be acceptable by the cipher. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function releases and clears the specified CCM context + * and underlying cipher sub-context. + * + * \param ctx The CCM context to clear. If this is \c NULL, the function + * has no effect. Otherwise, this must be initialized. + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); + +/** + * \brief This function encrypts a buffer using CCM. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. + * \param add_len The length of additional data in Bytes. + * This must be less than `2^16 - 2^8`. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function encrypts a buffer using CCM*. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \note When using this function in a variable tag length context, + * the tag length has to be encoded into the \p iv passed to + * this function. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer of + * at least \p add_len Bytes. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function performs a CCM authenticated decryption of a + * buffer. + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer + * of at least that \p add_len Bytes.. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. This indicates that the message is authentic. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +/** + * \brief This function performs a CCM* authenticated decryption of a + * buffer. + * + * \note When using this function in a variable tag length context, + * the tag length has to be decoded from \p iv and passed to + * this function as \p tag_len. (\p tag needs to be adjusted + * accordingly.) + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer of + * at least that \p add_len Bytes. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field in Bytes. + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is nos + * longer authenticated. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief The CCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ccm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CCM_ALT_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h new file mode 100644 index 000000000..3bcb43c9d --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CRYPTO_ECC_HW_H +#define CRYPTO_ECC_HW_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECP_ALT) || defined(MBEDTLS_ECP_INTERNAL_ALT) + +#include "mbedtls/ecp.h" +#include + +/* Crypto ECC H/W point operations */ +#define ECCOP_POINT_MUL (0x0UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_MODULE (0x1UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_POINT_ADD (0x2UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_POINT_DOUBLE (0x3UL << CRPT_ECC_CTL_ECCOP_Pos) + +/* Crypto ECC H/W modulus operations */ +#define MODOP_DIV (0x0UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_MUL (0x1UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_ADD (0x2UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_SUB (0x3UL << CRPT_ECC_CTL_MODOP_Pos) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This function checks whether a given group can be used + * for Crypto ECC H/W. + * + * \param grp ECP group + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int crypto_ecc_capable(const mbedtls_ecp_group *grp); + +/** + * \brief Initialize/Free Crypto ECC H/W + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + * \note crypto_ecp_init()/crypto_ecp_free() are like pre-op/post-op calls + * and they guarantee: + * + * 1. Paired + * 2. No overlapping + * 3. Upper public function cannot return when ECP alter. is still activated. + */ +int crypto_ecc_init(const mbedtls_ecp_group *grp); +void crypto_ecc_free(const mbedtls_ecp_group *grp); +/** + * \brief Configure ECCOP operation, start it, and wait for its completion + * + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply P + * \param P Point to multiply by m + * \param n Integer by which to multiply Q + * \param Q Point to be multiplied by n + * \param eccop ECCOP code. Could be ECCOP_POINT_MUL/ADD/DOUBLE + * \param blinding Blinding (SCAP) or not. + * Dependent on passed-in eccop, only partial parameters among m/P/n/Q are needed and checked. + * ECCOP_POINT_MUL R = m*P + * ECCOP_POINT_ADD R = P + Q + * ECCOP_POINT_DOUBLE R = 2*P + * + * \return 0 if successful + * + * \note P/Q must be normalized (= affine). R would be normalized. + * + * \note m/n could be negative. + * + * \note ECC accelerator doesn't support R = 0, and we need to detect it additionally. + * For R = P + Q or R = 2*P, we can detect all R = 0 cases. + * For R = m*P, we can detect all R = 0 cases only if grp->N (order) is a prime. + * + * \note According to ECCOP operation, n is unnecessary. But to be consistent with R = m*P + n*Q, + * n is kept with unused modifier. + * + * \note Blinding (SCAP) is applicable only for point multiplication. But for future extension, + * blinding is kept with all point operations. + * + */ +int crypto_ecc_run_eccop_add(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q, + bool blinding); +int crypto_ecc_run_eccop_double(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, + bool blinding); +int crypto_ecc_run_eccop_mul(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P, + bool blinding); +int crypto_ecc_run_eccop(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P, + const mbedtls_mpi *n, + const mbedtls_ecp_point *Q, + uint32_t eccop, + bool blinding); + +/** + * \brief Configure MODOP operation and wait for its completion + * + * \param r Destination MPI + * \param o1 Input MPI for first operand of MODOP + * \param o2 Input MPI for second operand of MODOP + * \param p Prime modulus + * \param pbits Bit number of p + * \param modop ECCOP code. Could be MODOP_ADD/SUB/MUL/DIV + * MODOP_ADD r = o1 + o2 mod p + * MODOP_SUB r = o1 - o2 mod p + * MODOP_MUL r = o1 * o2 mod p + * MODOP_DIV r = o1 / o2 mod p + * + * \return 0 if successful + * + * \note o1/o2 must be normalized (within [0, p - 1]). r would be normalized. + */ +int crypto_ecc_run_modop(mbedtls_mpi *r, + const mbedtls_mpi *o1, + const mbedtls_mpi *o2, + const mbedtls_mpi *p, + uint32_t pbits, + uint32_t modop); + +/** + * \brief Import X from ECC registers, little endian + * + * \param X Destination MPI + * \param eccreg Start of input ECC register + * \param eccreg_num Number of input ECC register + * + * \return 0 if successful + * + * \note Destination MPI is always non-negative. + */ +int crypto_ecc_mpi_read_eccreg( mbedtls_mpi *X, const volatile uint32_t *eccreg, size_t eccreg_num ); + +/** + * \brief Export X into ECC registers, little endian + * + * \param X Source MPI + * \param eccreg Start of ECC output registers + * \param eccreg_num Number of ECC output registers + * + * \return 0 if successful + * + * \note Source MPI cannot be negative. + * \note Fills the remaining MSB ECC registers with zeros if X doesn't cover all. + */ +int crypto_ecc_mpi_write_eccreg( const mbedtls_mpi *X, volatile uint32_t *eccreg, size_t eccreg_num ); + +/** + * \brief Abort Crypto ECC H/W + * + * \param timeout_us Timeout in microseconds. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int crypto_ecc_abort(uint32_t timeout_us); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_ECP_ALT || MBEDTLS_ECP_INTERNAL_ALT */ +#endif /* CRYPTO_ECC_HW_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h new file mode 100644 index 000000000..8c7c8d127 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h @@ -0,0 +1,187 @@ +/** + * \file ecp_alt.h + * + * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). + * + * The use of ECP in cryptography and TLS is defined in + * Standards for Efficient Cryptography Group (SECG): SEC1 + * Elliptic Curve Cryptography and + * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites + * for Transport Layer Security (TLS). + * + * RFC-2409: The Internet Key Exchange (IKE) defines ECP + * group types. + * + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_ECP_ALT_H +#define MBEDTLS_ECP_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_ECP_ALT) + +/* Enable Nuvoton's Crypto ECC H/W */ +#define NU_CRYPTO_ECC_ENABLE + +/* + * default mbed TLS elliptic curve arithmetic implementation + * + * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an + * alternative implementation for the whole module and it will replace this + * one.) + */ + +/** + * \brief The ECP group structure. + * + * We consider two types of curve equations: + * + * In both cases, the generator (\p G) for a prime-order subgroup is fixed. + * + * For Short Weierstrass, this subgroup is the whole curve, and its + * cardinality is denoted by \p N. Our code requires that \p N is an + * odd prime as mbedtls_ecp_mul() requires an odd number, and + * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. + * + * For Montgomery curves, we do not store \p A, but (A + 2) / 4, + * which is the quantity used in the formulas. Additionally, \p nbits is + * not the size of \p N but the required size for private keys. + * + * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. + * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the + * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer + * which is congruent mod \p P to the given MPI, and is close enough to \p pbits + * in size, so that it may be efficiently brought in the 0..P-1 range by a few + * additions or subtractions. Therefore, it is only an approximative modular + * reduction. It must return 0 on success and non-zero on failure. + * + * \note Alternative implementations must keep the group IDs distinct. If + * two group structures have the same ID, then they must be + * identical. + * + */ +typedef struct mbedtls_ecp_group +{ + mbedtls_ecp_group_id id; /*!< An internal group identifier. */ + mbedtls_mpi P; /*!< The prime modulus of the base field. */ + mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For + Montgomery curves: (A + 2) / 4. */ + mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. + For Montgomery curves: unused. */ + mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ + mbedtls_mpi N; /*!< The order of \p G. */ + size_t pbits; /*!< The number of bits in \p P.*/ + size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. + For Montgomery curves: the number of bits in the + private keys. */ + unsigned int h; /*!< \internal 1 if the constants are static. */ + int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction + mod \p P (see above).*/ + int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ + int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ + void *t_data; /*!< Unused. */ + mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ + size_t T_size; /*!< The number of pre-computed points. */ + +#if defined(NU_CRYPTO_ECC_ENABLE) + int hw_init; /*!< Initialized Crypto ECC H/W or not. */ +#endif +} +mbedtls_ecp_group; + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h, or define them using the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_ECP_MAX_BITS) +/** + * The maximum size of the groups, that is, of \c N and \c P. + */ +#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ +#endif + +#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) +#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) + +#if !defined(MBEDTLS_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: 6. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ +#endif /* MBEDTLS_ECP_WINDOW_SIZE */ + +#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ + +/* \} name SECTION: Module settings */ + +#endif /* MBEDTLS_ECP_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecp.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h new file mode 100644 index 000000000..6903af4d5 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECP_HELPER_H +#define ECP_HELPER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" + +/** + * \brief Check if MPI has been normalized + * + * \param N Input MPI which is to check + * \param P Prime modulus + * + * \return 0 if not normalized, + * 1 if normalized + */ +#define ECP_HELPER_MPI_IS_NORM(N, P) \ + ((mbedtls_mpi_cmp_int(&N, 0) >= 0) && (mbedtls_mpi_cmp_mpi(&N, &P) < 0)) + +/** + * \brief Normalize MPI if it is not normalized yet + * + * \param R Holds pointer to normalized MPI (N1 or N2) + * \param N1 Input MPI which is to normalize + * \param N2 Output MPI which holds normalized N1 if N1 is not normalized yet + * \param P Prime modulus + */ +#define ECP_HELPER_MPI_NORM(R, N1, N2, P) \ + do { \ + if (ECP_HELPER_MPI_IS_NORM(N1, P)) { \ + *R = &N1; \ + } else { \ + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&N2, &N1, &P)); \ + *R = &N2; \ + } \ + } while(0) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This function deduces y coordinate from x coordinate + * for a ECP point expressed in compact representation. + * + * \param grp The ECP group to be exported. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param y Deduced y coordinate which is smaller. The other would be + * \p grp->P - \p y. \p y must point to an initialized MPI. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a Curve25519 or Curve448 curve. + * \return Another negative error code on other kinds of failure. + */ +int ecp_helper_deduce_y(const mbedtls_ecp_group *grp, + mbedtls_mpi *y, + const mbedtls_mpi *x); + +#ifdef __cplusplus +} +#endif + +#endif /* ECP_HELPER_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h new file mode 100644 index 000000000..a680e897d --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h @@ -0,0 +1,72 @@ +/** + * \file gcm.h + * + * \brief This file contains GCM definitions and functions. + * + * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. + * + * For more information on GCM, see NIST SP 800-38D: Recommendation for + * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_GCM_ALT_H +#define MBEDTLS_GCM_ALT_H + +#if defined(MBEDTLS_GCM_ALT) +#include "mbed_toolchain.h" +#define MAX_GCM_BUF 256 +#define GCM_PBLOCK_SIZE (MAX_GCM_BUF) /* NOTE: This value must be 16 bytes alignment. This value must > size of A */ + + +/** + * \brief The GCM context structure. + */ +typedef struct mbedtls_gcm_context +{ + uint32_t len; /*!< The total length of the encrypted data. */ + int mode; /*!< The operation to perform: + #MBEDTLS_GCM_ENCRYPT or + #MBEDTLS_GCM_DECRYPT. */ + + uint32_t keySize; /* Key size unit is bytes: 16(128 bits)/24(192 bits)/32(256 bits) */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ + uint32_t iv[4]; /* IV for next block cipher */ + uint32_t keys[8]; /* Cipher key */ + uint32_t basicOpt; /* Basic option of AES controller */ + MBED_ALIGN(4) uint8_t gcm_buf[MAX_GCM_BUF]; /* buffer for GCM DMA input */ + MBED_ALIGN(4) uint8_t out_buf[MAX_GCM_BUF+16]; /* buffer for GCM DMA output */ + MBED_ALIGN(4) uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */ + MBED_ALIGN(4) uint8_t fb_buf2[72]; /* feedback buffer 2 for GCM DMA */ + uint8_t tag[16]; /* Tag */ + uint32_t gcm_buf_bytes; /* Bytes in gcm_buf */ + uint32_t firstFlag; /* A flag for the first data block */ + uint32_t endFlag; /* final block is done */ + uint32_t pcntLen; /* PCNT length*/ +// uint8_t *add; +// size_t addlen; +} +mbedtls_gcm_context; + +#endif /* MBEDTLS_GCM_ALT */ + +#endif /* gcm.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h new file mode 100644 index 000000000..71ed198f0 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_DEVICE_H +#define MBEDTLS_DEVICE_H + +#define MBEDTLS_SHA1_ALT +#define MBEDTLS_SHA256_ALT +#define MBEDTLS_SHA512_ALT + +#define MBEDTLS_AES_ALT +#define MBEDTLS_GCM_ALT +#define MBEDTLS_CCM_ALT + +#define MBEDTLS_ECP_ALT + +#if !defined(MBEDTLS_ECP_ALT) + +#define MBEDTLS_ECP_INTERNAL_ALT + +/* Support for Weierstrass curves with Jacobi representation */ +#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +#define MBEDTLS_ECP_ADD_MIXED_ALT +#define MBEDTLS_ECP_DOUBLE_JAC_ALT +#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT + +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +#endif /* !MBEDTLS_ECP_ALT */ + +#define MBEDTLS_RSA_ALT + +#endif /* MBEDTLS_DEVICE_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h new file mode 100644 index 000000000..b3bd67a07 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CRYPTO_RSA_HW_H +#define CRYPTO_RSA_HW_H + +#include "mbedtls/rsa.h" + +#if defined(MBEDTLS_RSA_ALT) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize/Free Crypto RSA H/W + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + * \note crypto_rsa_init()/crypto_rsa_free() are like pre-op/post-op calls + * and they guarantee: + * + * 1. Paired + * 2. No overlapping + * 3. Upper public function cannot return when RSA alter. is still activated. + */ +int crypto_rsa_init(mbedtls_rsa_context *ctx); +void crypto_rsa_free(mbedtls_rsa_context *ctx); + +/** + * \brief Query whether or not RSA H/W supports encrypt/decrypt operation in this context + * in normal/CRT algorithm + * + * \param ctx The initialized RSA context to use. + * \param decrypt true for decrypt, or encrypt. + * \param crt true for CRT algorithm, or normal. + * \param blinding Blinding (SCAP) or not. + * + * \return \c 1 on capable, or 0 on incapable. + * + * \note Blinding is applicable only for decrypt operation. + * \note CRT is applicable only for decrypt operation. + */ +int crypto_rsa_encrypt_norm_capable(const mbedtls_rsa_context *ctx); +int crypto_rsa_decrypt_norm_capable(const mbedtls_rsa_context *ctx, bool blinding); +int crypto_rsa_decrypt_crt_capable(const mbedtls_rsa_context *ctx, bool blinding); +int crypto_rsa_crypt_capable(const mbedtls_rsa_context *ctx, + bool decrypt, + bool crt, + bool blinding); +/** + * \brief Run RSA encrypt/decrypt operation in normal/CRT algorithm + * + * \param ctx The initialized RSA context to use. + * \param decrypt true for decrypt, or encrypt. + * \param crt true for CRT algorithm, or normal. + * \param blinding Blinding (SCAP) or not. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int crypto_rsa_encrypt_norm(mbedtls_rsa_context *ctx, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_decrypt_norm(mbedtls_rsa_context *ctx, + bool blinding, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_decrypt_crt(mbedtls_rsa_context *ctx, + bool blinding, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_crypt(mbedtls_rsa_context *ctx, + bool decrypt, + bool crt, + bool blinding, + const unsigned char *input, + unsigned char *output); + +/** + * \brief Abort Crypto RSA H/W + * + * \param ctx The initialized RSA context to use. + * \param timeout_us Timeout in microseconds. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int crypto_rsa_abort(mbedtls_rsa_context *ctx, + uint32_t timeout_us); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_RSA_ALT */ + +#endif /* CRYPTO_RSA_HW_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h new file mode 100644 index 000000000..86201c520 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h @@ -0,0 +1,109 @@ +/** + * \file rsa_alt.h + * + * \brief This file provides an API for the RSA public-key cryptosystem. + * + * The RSA public-key cryptosystem is defined in Public-Key + * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption + * and Public-Key Cryptography Standards (PKCS) #1 v2.1: + * RSA Cryptography Specifications. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_RSA_ALT_H +#define MBEDTLS_RSA_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" +#include "mbedtls/md.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_RSA_ALT) +// Regular implementation +// + +/* Enable Nuvoton's Crypto RSA H/W */ +#define NU_CRYPTO_RSA_ENABLE + +/** + * \brief The RSA context structure. + * + * \note Direct manipulation of the members of this structure + * is deprecated. All manipulation should instead be done through + * the public interface functions. + */ +typedef struct mbedtls_rsa_context +{ + int ver; /*!< Always 0.*/ + size_t len; /*!< The size of \p N in Bytes. */ + + mbedtls_mpi N; /*!< The public modulus. */ + mbedtls_mpi E; /*!< The public exponent. */ + + mbedtls_mpi D; /*!< The private exponent. */ + mbedtls_mpi P; /*!< The first prime factor. */ + mbedtls_mpi Q; /*!< The second prime factor. */ + + mbedtls_mpi DP; /*!< D % (P - 1). */ + mbedtls_mpi DQ; /*!< D % (Q - 1). */ + mbedtls_mpi QP; /*!< 1 / (Q % P). */ + + mbedtls_mpi RN; /*!< cached R^2 mod N. */ + + mbedtls_mpi RP; /*!< cached R^2 mod P. */ + mbedtls_mpi RQ; /*!< cached R^2 mod Q. */ + + mbedtls_mpi Vi; /*!< The cached blinding value. */ + mbedtls_mpi Vf; /*!< The cached un-blinding value. */ + + int padding; /*!< Selects padding mode: + #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and + #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ + int hash_id; /*!< Hash identifier of mbedtls_md_type_t type, + as specified in md.h for use in the MGF + mask generating function used in the + EME-OAEP and EMSA-PSS encodings. */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */ +#endif + +#if defined(NU_CRYPTO_RSA_ENABLE) + int hw_init; /*!< Initialized Crypto RSA H/W or not. */ +#endif +} +mbedtls_rsa_context; + +#endif /* MBEDTLS_RSA_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* rsa_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h new file mode 100644 index 000000000..3c4efdac8 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA1_ALT_H +#define MBEDTLS_SHA1_ALT_H + +#include "mbedtls/sha1.h" + +#if defined(MBEDTLS_SHA1_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha1_context_s; + +/** + * \brief SHA-1 context structure + */ +typedef struct mbedtls_sha1_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha1_context; + +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-1 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha1_clone( mbedtls_sha1_context *dst, + const mbedtls_sha1_context *src ); + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + * + * \returns error code + */ +int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + * + * \returns error code + */ +int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ); + +/* Internal use */ +int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief SHA-1 context setup + * + * \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0 + * + * \param ctx The SHA-1 context to be initialized. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param output The SHA-1 checksum result. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, + unsigned char output[20] ); + +/** + * \brief SHA-1 process data block (internal use only) + * + * \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param data The data block being processed. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, + const unsigned char data[64] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA1_ALT */ + +#endif /* sha1_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h new file mode 100644 index 000000000..bd8669a43 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA256_ALT_H +#define MBEDTLS_SHA256_ALT_H + +#include "mbedtls/sha256.h" + +#if defined(MBEDTLS_SHA256_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha256_context_s; + +/** + * \brief SHA-256 context structure + */ +typedef struct mbedtls_sha256_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha256_context; + +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-256 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha256_clone( mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src ); + +/** + * \brief SHA-256 context setup + * + * \param ctx context to be initialized + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \returns error code + */ +int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); + +/** + * \brief SHA-256 process buffer + * + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-224/256 checksum result + * + * \returns error code + */ +int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ); + +/* Internal use */ +int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param is224 Determines which function to use. + *
  • 0: Use SHA-256.
  • + *
  • 1: Use SHA-224.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, + int is224 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-256 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param output The SHA-224or SHA-256 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, + unsigned char output[32] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-256 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA256_ALT */ + +#endif /* sha256_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h new file mode 100644 index 000000000..b6decc2f4 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA512_ALT_H +#define MBEDTLS_SHA512_ALT_H + +#include "mbedtls/sha512.h" + +#if defined(MBEDTLS_SHA512_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha512_context_s; + +/** + * \brief SHA-512 context structure + */ +typedef struct mbedtls_sha512_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha512_context; + +/** + * \brief Initialize SHA-512 context + * + * \param ctx SHA-512 context to be initialized + */ +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); + +/** + * \brief Clear SHA-512 context + * + * \param ctx SHA-512 context to be cleared + */ +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-512 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ); + +/** + * \brief SHA-512 context setup + * + * \param ctx context to be initialized + * \param is384 0 = use SHA512, 1 = use SHA384 + * + * \returns error code + */ +int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); + +/** + * \brief SHA-512 process buffer + * + * \param ctx SHA-512 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-512 final digest + * + * \param ctx SHA-512 context + * \param output SHA-384/512 checksum result + * + * \returns error code + */ +int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ); + +/* Internal use */ +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-384 or SHA-512 checksum + * calculation. + * + * \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 + * + * \param ctx The SHA-512 context to initialize. + * \param is384 Determines which function to use. + *
  • 0: Use SHA-512.
  • + *
  • 1: Use SHA-384.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is384 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-512 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-512 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param output The SHA-384 or SHA-512 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-512 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA512_ALT */ + +#endif /* sha512_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h new file mode 100644 index 000000000..43219d701 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA_ALT_HW_H +#define MBEDTLS_SHA_ALT_HW_H + +#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT) + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Max size of SHA block in bytes + * + * SHA-160/224/256: 64 bytes + * SHA-384/512: 128 bytes + * + * \note Support SHA1/2 only, no SHA3 + */ +#define NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES 128 + +/** + * \brief Max size of SHA DMA block run in bytes + * + * \note DMA cascade mode requires block-aligned except for the last block. + * \note This also defines DMA intermediary buffer size. + */ +#define NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES \ + (NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES * 4) + +/** + * \brief Max size of SHA feedback information in words, used in DMA cascade mode + * + * SHA1/2: 54 words + * SHA3: 88 words + * + * \note Support SHA1/2 only, no SHA3 + * \note According to spec, reserve 54 words for SHA1/2. But per real + * test, SHA H/W will overwrite beyond 54 words. Workaround by + * reserving 88 words anyway. + */ +#define NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS 88 + +/** + * \brief SHA context structure + * + * \note SHA type/opmode + * 1. For type, borrow from opmode defines and can only be SHA_MODE_SHA1/SHA256/SHA512. + * 2. Initialize opmode/digestsize dependent on type + * 3. For SHA_MODE_SHA256/512, opmode will change to SHA_MODE_SHA224/384 + * when is224_384 is non-zero in the call to crypto_sha_starts(). + * 4. Following above, for opmode being SHA_MODE_SHA224/384, change digestsize to 28/48 + */ +typedef struct { + /* These fields will initialize at crypto_sha_init() */ + uint32_t type; /*!< SHA type */ + uint32_t opmode; /*!< SHA operation mode */ + uint32_t digestsize; /*!< SHA digest size */ + int err_hw_accel; /*!< Mbed TLS error code for the SHA type */ + int err_bad_input; /*!< Mbed TLS error code for the SHA type */ + + /* These fields will initialize at crypto_sha_starts() */ + uint32_t total; /*!< number of bytes processed */ + union { + uint8_t buffer[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES]; /*!< data block being processed. Max of SHA-1/SHA-256/SHA-512 */ + uint32_t buffer_u32[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES/4]; /*!< make buffer word aligned */ + }; + uint16_t buffer_left; + uint16_t blocksize; /*!< block size */ + uint32_t blocksize_mask; /*!< block size mask */ + int is224_384; /*!< 0 => SHA-256/SHA-512, else SHA-224/384 */ + uint32_t fbinfo[NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS]; /*!< feedback information in DMA cascade mode */ +} +crypto_sha_context; + +void crypto_sha_init(crypto_sha_context *ctx, uint32_t type); +void crypto_sha_free(crypto_sha_context *ctx); +int crypto_sha_starts(crypto_sha_context *ctx, int is224_384); +int crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen); +int crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int isfirst, int islast); +int crypto_sha_finish(crypto_sha_context *ctx, unsigned char output[], size_t olen); +int crypto_sha_getdigest(unsigned char output[], size_t olen); + +#if defined(MBEDTLS_SHA1_ALT) + +void mbedtls_sha1_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha1_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha1_hw_starts( crypto_sha_context *ctx ); +int mbedtls_sha1_hw_update( crypto_sha_context *ctx, const unsigned char *input, size_t ilen ); +int mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] ); +int mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] ); + +#endif /* MBEDTLS_SHA1_ALT */ + +#if defined(MBEDTLS_SHA256_ALT) + +void mbedtls_sha256_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha256_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224 ); +int mbedtls_sha256_hw_update( crypto_sha_context *ctx, const unsigned char *input, + size_t ilen ); +int mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32] ); +int mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] ); + +#endif /* MBEDTLS_SHA256_ALT */ + +#if defined(MBEDTLS_SHA512_ALT) + +void mbedtls_sha512_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha512_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha512_hw_starts( crypto_sha_context *ctx, int is384 ); +int mbedtls_sha512_hw_update( crypto_sha_context *ctx, const unsigned char *input, + size_t ilen ); +int mbedtls_sha512_hw_finish( crypto_sha_context *ctx, unsigned char output[64] ); +int mbedtls_sha512_hw_process( crypto_sha_context *ctx, const unsigned char data[128] ); + +#endif /* MBEDTLS_SHA512_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */ + +#endif /* sha_alt.h */ diff --git a/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h b/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h index b4c83706b..4fb9103d3 100644 --- a/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h +++ b/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h @@ -122,7 +122,7 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyabletop = wrap; } +static inline void pwm_set_chan_level(uint slice_num, uint chan, uint16_t level); + /** \brief Initialise a PWM with settings from a configuration object * \ingroup hardware_pwm * @@ -188,12 +190,12 @@ static inline void pwm_config_set_wrap(pwm_config *c, uint16_t wrap) { * \param start If true the PWM will be started running once configured. If false you will need to start * manually using \ref pwm_set_enabled() or \ref pwm_set_mask_enabled() */ -static inline void pwm_init(uint slice_num, pwm_config *c, bool start) { +static inline void pwm_init(uint slice_num, uint chan, pwm_config *c, bool start) { check_slice_num_param(slice_num); pwm_hw->slice[slice_num].csr = 0; pwm_hw->slice[slice_num].ctr = PWM_CH0_CTR_RESET; - pwm_hw->slice[slice_num].cc = PWM_CH0_CC_RESET; + pwm_set_chan_level(slice_num, chan, PWM_CH0_CC_A_RESET); pwm_hw->slice[slice_num].top = c->top; pwm_hw->slice[slice_num].div = c->div; pwm_hw->slice[slice_num].csr = c->csr | (bool_to_bit(start) << PWM_CH0_CSR_EN_LSB); diff --git a/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h b/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h index 61d480678..9ca283c8f 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h +++ b/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h @@ -52,6 +52,11 @@ #define AFIO_REMAP_TIM2_PARTIAL_1 14 #define AFIO_REMAP_TIM2_PARTIAL_2 15 #define AFIO_REMAP_TIM4_ENABLE 16 +#define AFIO_REMAP_TIM9_ENABLE 17 +#define AFIO_REMAP_TIM10_ENABLE 18 +#define AFIO_REMAP_TIM11_ENABLE 19 +#define AFIO_REMAP_TIM13_ENABLE 20 +#define AFIO_REMAP_TIM14_ENABLE 21 #endif diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h index dbdadf962..c8188eb4e 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h @@ -77,39 +77,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct analogin_s { ADC_HandleTypeDef handle; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h index 660403eb5..793badc15 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h @@ -109,6 +109,31 @@ static inline void stm_pin_SetAFPin(GPIO_TypeDef *gpio, PinName pin, uint32_t af case AFIO_REMAP_TIM4_ENABLE: __HAL_AFIO_REMAP_TIM4_ENABLE(); break; +#if defined(AFIO_MAPR2_TIM9_REMAP) + case AFIO_REMAP_TIM9_ENABLE: + __HAL_AFIO_REMAP_TIM9_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM10_REMAP) + case AFIO_REMAP_TIM10_ENABLE: + __HAL_AFIO_REMAP_TIM10_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM11_REMAP) + case AFIO_REMAP_TIM11_ENABLE: + __HAL_AFIO_REMAP_TIM11_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM13_REMAP) + case AFIO_REMAP_TIM13_ENABLE: + __HAL_AFIO_REMAP_TIM13_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM14_REMAP) + case AFIO_REMAP_TIM14_ENABLE: + __HAL_AFIO_REMAP_TIM14_ENABLE(); + break; +#endif default: break; } diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h index d69e9e7b6..c95c440c8 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h @@ -90,41 +90,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct dac_s { DACName dac; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h index ef8dc2919..ed253af45 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h @@ -108,39 +108,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct analogin_s { ADC_HandleTypeDef handle; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h index 55dea741c..062116229 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h @@ -89,41 +89,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h index 647c45253..183cf5416 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h @@ -88,41 +88,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct dac_s { DACName dac; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h index e981df8aa..655995565 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h @@ -25,20 +25,28 @@ #define MBED_ROM_SIZE 0x100000 // 1 MB #endif +// 0x20000000 - 0x2001FFFF 128K DTCM +// 0x24000000 - 0x2404FFFF 320K AXI SRAM +// 0x30000000 - 0x30003FFF 16K SRAM1 +// 0x30004000 - 0x30007FFF 16K SRAM2 +// 0x38000000 - 0x38003FFF 16K SRAM4 + #if !defined(MBED_RAM_START) -#define MBED_RAM_START 0x24000000 +#define MBED_RAM_START 0x20000000 #endif #if !defined(MBED_RAM_SIZE) -// 0x38000000 - 0x38003FFF 16K SRAM4 -// 0x30004000 - 0x30007FFF 16K SRAM2 -// 0x30000000 - 0x30003FFF 16K SRAM1 -// 0x24000000 - 0x2404FFFF 320K AXI SRAM -// 0x20000000 - 0x2001FFFF 128K DTCM -#define MBED_RAM_SIZE 0x50000 // 320 KB +#define MBED_RAM_SIZE 0x20000 // 128 KB +#endif + +#if !defined(MBED_RAM1_START) +#define MBED_RAM_1START 0x24000000 +#endif + +#if !defined(MBED_RAM1_SIZE) +#define MBED1_RAM_SIZE 0x50000 // 320 KB #endif #define NVIC_NUM_VECTORS 180 #define NVIC_RAM_VECTOR_ADDRESS MBED_RAM_START - #endif diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h index 628ffa747..02ed6ea8c 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -103,39 +103,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - #if DEVICE_ANALOGIN struct analogin_s { ADC_HandleTypeDef handle; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h index 8ed217b88..4becf27ff 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h @@ -91,41 +91,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - #if DEVICE_FLASH struct flash_s { /* nothing to be stored for now */ diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h index 136a582b3..d41e92738 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h @@ -87,41 +87,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h index c06bdd717..ed7d2a8db 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h @@ -97,39 +97,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h index a5e3d328e..69e9c5bc2 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h @@ -97,39 +97,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h index 515846edc..a3b501e89 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h @@ -80,39 +80,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h index a8fd7b93d..d3c601b35 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h @@ -83,39 +83,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/device.h b/cores/arduino/mbed/targets/TARGET_STM/device.h index a2fd83c54..b30041afd 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/device.h +++ b/cores/arduino/mbed/targets/TARGET_STM/device.h @@ -36,6 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +#include "stm_i2c_api.h" #if DEVICE_USTICKER #include "us_ticker_defines.h" diff --git a/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h b/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h new file mode 100644 index 000000000..7ae17f4b8 --- /dev/null +++ b/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h @@ -0,0 +1,102 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016-2022 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef MBED_STM_I2C_API_H +#define MBED_STM_I2C_API_H + +#include "i2c_device.h" + +#include + +/** + * State of the I2C peripheral. + * Note: SB stands for Single Byte, TR stands for Transaction + */ +typedef enum stm_i2c_state +{ + STM_I2C_IDLE, + STM_I2C_PENDING_START, // This state is created either by calling start(), or by completing a transaction with the repeated start flag + STM_I2C_SB_READ_IN_PROGRESS, + STM_I2C_SB_WRITE_IN_PROGRESS, + STM_I2C_TR_READ_IN_PROGRESS, + STM_I2C_TR_WRITE_IN_PROGRESS, + STM_I2C_ASYNC_READ_IN_PROGRESS, + STM_I2C_ASYNC_WRITE_IN_PROGRESS +} stm_i2c_state; + +#ifdef I2C_IP_VERSION_V2 + +/** + * Extended I2C structure containing STM-specific data + */ +struct i2c_s { + /* The 1st 2 members I2CName i2c + * and I2C_HandleTypeDef handle should + * be kept as the first members of this struct + * to ensure i2c_get_obj to work as expected + */ + I2CName i2c; + I2C_HandleTypeDef handle; + uint8_t index; + int hz; + PinName sda; + PinName scl; + IRQn_Type event_i2cIRQ; + IRQn_Type error_i2cIRQ; + volatile stm_i2c_state state; + + /// Used to pass events (the I2C_EVENT_xxx defines) from ISRs to the main thread + volatile uint8_t event; + + int current_hz; +#if DEVICE_I2CSLAVE + uint8_t slave; + volatile uint8_t pending_slave_tx_master_rx; + volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint16_t slave_rx_buffer_size; + volatile uint16_t slave_rx_count; +#endif +#if DEVICE_I2C_ASYNCH + /// Address that the current asynchronous transaction is talking to + uint32_t address; + + /// If true, send a stop at the end of the current asynchronous transaction + bool stop; + + /// Specifies which events (the I2C_EVENT_xxx defines) can be passed up to the application from the IRQ handler + uint8_t available_events; +#endif + +#if STATIC_PINMAP_READY + int sda_func; + int scl_func; +#endif +}; + +#endif + +// Macro that can be used to set the state of an I2C object. +// Compiles to nothing for IP v1 +#ifdef I2C_IP_VERSION_V2 +#define STM_I2C_SET_STATE(i2c_s, new_state) i2c_s->state = new_state +#else +#define STM_I2C_SET_STATE(i2c_s, new_state) (void)i2c_s +#endif + +#endif //MBED_STM_I2C_API_H diff --git a/giga.variables b/giga.variables index c3d7ea373..83045721f 100644 --- a/giga.variables +++ b/giga.variables @@ -1,5 +1,5 @@ export FLAVOUR="giga" export VARIANTS=("GIGA PORTENTA_H7_M4") export FQBNS=("giga") -export LIBRARIES=("MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 PDM Portenta_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib OV7670 mbed-memory-status Scheduler USBMSD SocketWrapper MCUboot") +export LIBRARIES=("MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 PDM Arduino_H7_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib OV7670 mbed-memory-status Scheduler USBMSD USBMIDI SocketWrapper MCUboot Arduino_CAN") export BOOTLOADERS=("GIGA") diff --git a/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino index 522f6c345..78d1c68a3 100644 --- a/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino +++ b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino @@ -35,7 +35,7 @@ void loop() */ uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0}; memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt)); - CanMsg msg(CAN_ID, sizeof(msg_data), msg_data); + CanMsg msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data); /* Transmit the CAN message, capture and display an * error core in case of failure. diff --git a/libraries/Arduino_CAN/src/Arduino_CAN.cpp b/libraries/Arduino_CAN/src/Arduino_CAN.cpp index fce0ce3a2..de74c22c5 100644 --- a/libraries/Arduino_CAN/src/Arduino_CAN.cpp +++ b/libraries/Arduino_CAN/src/Arduino_CAN.cpp @@ -48,12 +48,14 @@ void Arduino_CAN::end() int Arduino_CAN::write(CanMsg const & msg) { + bool const is_standard_id = msg.isStandardId(); + mbed::CANMessage const can_msg( - msg.id, + is_standard_id ? msg.getStandardId() : msg.getExtendedId(), msg.data, msg.data_length, CANData, - CANStandard); + is_standard_id ? CANStandard : CANExtended); return _can.write(can_msg); } @@ -65,8 +67,10 @@ size_t Arduino_CAN::available() if (msg_read) { + bool const is_standard_id = (can_msg.format == CANStandard); + CanMsg const msg( - can_msg.id, + is_standard_id ? CanStandardId(can_msg.id) : CanExtendedId(can_msg.id), can_msg.len, can_msg.data); diff --git a/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino b/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino index d9218000d..4c1328d21 100644 --- a/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino +++ b/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino @@ -1,28 +1,40 @@ -#include "camera.h" -#include "Portenta_lvgl.h" -#include "Portenta_Video.h" +#include "arducam_dvp.h" +#include "Arduino_H7_Video.h" +#include "dsi.h" +#include "SDRAM.h" -#if 0 -#include "gc2145.h" -GC2145 galaxyCore; -Camera cam(galaxyCore); -#define IMAGE_MODE CAMERA_RGB565 -#else -#include "himax.h" +// This example only works with Greyscale cameras (due to the palette + resize&rotate algo) +#define ARDUCAM_CAMERA_HM01B0 + +#ifdef ARDUCAM_CAMERA_HM01B0 +#include "Himax_HM01B0/himax.h" HM01B0 himax; Camera cam(himax); #define IMAGE_MODE CAMERA_GRAYSCALE +#elif defined(ARDUCAM_CAMERA_HM0360) +#include "Himax_HM0360/hm0360.h" +HM0360 himax; +Camera cam(himax); +#define IMAGE_MODE CAMERA_GRAYSCALE +#elif defined(ARDUCAM_CAMERA_OV767X) +#include "OV7670/ov767x.h" +// OV7670 ov767x; +OV7675 ov767x; +Camera cam(ov767x); +#define IMAGE_MODE CAMERA_RGB565 +#elif defined(ARDUCAM_CAMERA_GC2145) +#include "GC2145/gc2145.h" +GC2145 galaxyCore; +Camera cam(galaxyCore); +#define IMAGE_MODE CAMERA_RGB565 #endif -/* - Other buffer instantiation options: - FrameBuffer fb(0x30000000); - FrameBuffer fb(320,240,2); -*/ +// The buffer used to capture the frame FrameBuffer fb; - -unsigned long lastUpdate = 0; - +// The buffer used to rotate and resize the frame +FrameBuffer outfb; +// The buffer used to rotate and resize the frame +Arduino_H7_Video Display(800, 480, GigaDisplayShield); void blinkLED(uint32_t count = 0xFFFFFFFF) { @@ -34,68 +46,61 @@ void blinkLED(uint32_t count = 0xFFFFFFFF) delay(50); // wait for a second } } -void LCD_ST7701_Init(); uint32_t palette[256]; void setup() { - pinMode(PA_1, OUTPUT); - digitalWrite(PA_1, HIGH); - - pinMode(PD_4, OUTPUT); - digitalWrite(PD_4, LOW); - // Init the cam QVGA, 30FPS if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30)) { blinkLED(); } + // Setup the palette to convert 8 bit greyscale to 32bit greyscale for (int i = 0; i < 256; i++) { palette[i] = 0xFF000000 | (i << 16) | (i << 8) | i; } - giga_init_video(); - LCD_ST7701_Init(); + Display.begin(); - blinkLED(5); + if (IMAGE_MODE == CAMERA_GRAYSCALE) { + dsi_configueCLUT((uint32_t*)palette); + } + outfb.setBuffer((uint8_t*)SDRAM.malloc(1024 * 1024)); - stm32_configue_CLUT((uint32_t*)palette); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); + // clear the display (gives a nice black background) + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); } -#include "avir.h" +#define HTONS(x) (((x >> 8) & 0x00FF) | ((x << 8) & 0xFF00)) void loop() { - lastUpdate = millis(); - - // Grab frame and write to serial + // Grab frame and write to another framebuffer if (cam.grabFrame(fb, 3000) == 0) { - //avir :: CImageResizer<> ImageResizer( 8 ); - //ImageResizer.resizeImage( (uint8_t*)fb.getBuffer(), 320, 240, 0, (uint8_t*)outfb.getBuffer(), 480, 320, 1, 0 ); - static FrameBuffer outfb(0x30000000); - //static FrameBuffer outfb(getFramebufferEnd()); - for (int i = 0; i < 300; i++) { + + // double the resolution and transpose (rotate by 90 degrees) in the same step + // this only works if the camera feed is 320x240 and the area where we want to display is 640x480 + for (int i = 0; i < 320; i++) { for (int j = 0; j < 240; j++) { - //((uint8_t*)outfb.getBuffer())[j * 240 + (320 - i)] = ((uint8_t*)fb.getBuffer())[i * 320 + j]; -#if 1 - ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i*2+1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i*2+1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; -#endif -#if 0 - ((uint8_t*)outfb.getBuffer())[j + i * 240] = ((uint8_t*)fb.getBuffer())[i + j * 320]; -#endif + if (IMAGE_MODE == CAMERA_GRAYSCALE) { + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + } else { + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + } } } - //stm32_LCD_DrawImage((void*)outfb.getBuffer(), (void*)getNextFrameBuffer(), 240, 320, DMA2D_INPUT_L8); - stm32_LCD_DrawImage((void*)outfb.getBuffer(), (void*)getNextFrameBuffer(), 480, 640, DMA2D_INPUT_L8); - //stm32_LCD_DrawImage((void*)fb.getBuffer(), (void*)getNextFrameBuffer(), 320, 240, DMA2D_INPUT_L8); + dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 640, IMAGE_MODE == CAMERA_GRAYSCALE ? DMA2D_INPUT_L8 : DMA2D_INPUT_RGB565); + dsi_drawCurrentFrameBuffer(); } else { blinkLED(20); } -} +} \ No newline at end of file diff --git a/libraries/Camera/examples/GigaCameraDisplay/avir.h b/libraries/Camera/examples/GigaCameraDisplay/avir.h deleted file mode 100644 index ce4cec87a..000000000 --- a/libraries/Camera/examples/GigaCameraDisplay/avir.h +++ /dev/null @@ -1,6644 +0,0 @@ -//$ nobt -//$ nocpp - -/** - * @file avir.h - * - * @brief The "main" inclusion file with all required classes and functions. - * - * This is the "main" inclusion file for the "AVIR" image resizer. This - * inclusion file contains implementation of the AVIR image resizing algorithm - * in its entirety. Also includes several classes and functions that can be - * useful elsewhere. - * - * AVIR Copyright (c) 2015-2021 Aleksey Vaneev - * - * @mainpage - * - * @section intro_sec Introduction - * - * Description is available at https://github.com/avaneev/avir - * - * AVIR is devoted to women. Your digital photos can look good at any size! - * - * Please credit the author of this library in your documentation in the - * following way: "AVIR image resizing algorithm designed by Aleksey Vaneev". - * - * @section license License - * - * MIT License - * - * Copyright (c) 2015-2021 Aleksey Vaneev - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * @version 3.0 - */ - -#ifndef AVIR_CIMAGERESIZER_INCLUDED -#define AVIR_CIMAGERESIZER_INCLUDED - -#include -#include -#include -#include - -namespace avir { - -/** - * The macro defines AVIR version string. - */ - -#define AVIR_VERSION "3.0" - -/** - * The macro equals to "pi" constant, fills 53-bit floating point mantissa. - * Undefined at the end of file. - */ - -#define AVIR_PI 3.1415926535897932 - -/** - * The macro equals to "pi divided by 2" constant, fills 53-bit floating - * point mantissa. Undefined at the end of file. - */ - -#define AVIR_PId2 1.5707963267948966 - -/** - * A special macro that defines empty copy-constructor and copy operator with - * the "private:" prefix. This macro should be used in classes that cannot be - * copied in a standard C++ way. - */ - -#define AVIR_NOCTOR( ClassName ) \ - private: \ - ClassName( const ClassName& ) { } \ - ClassName& operator = ( const ClassName& ) { return( *this ); } - -/** - * Rounding function, based on the (int) typecast. Biased result. Not suitable - * for numbers >= 2^31. - * - * @param d Value to round. - * @return Rounded value. Some bias may be introduced. - */ - -template< class T > -inline T round( const T d ) -{ - return( d < (T) 0 ? -(T) (int) ( (T) 0.5 - d ) : - (T) (int) ( d + (T) 0.5 )); -} - -/** - * Template function "clamps" (clips) the specified value so that it is not - * lesser than "minv", and not greater than "maxv". - * - * @param Value Value to clamp. - * @param minv Minimal allowed value. - * @param maxv Maximal allowed value. - * @return The clamped value. - */ - -template< class T > -inline T clamp( const T& Value, const T minv, const T maxv ) -{ - if( Value < minv ) - { - return( minv ); - } - else - if( Value > maxv ) - { - return( maxv ); - } - else - { - return( Value ); - } -} - -/** - * Power 2.4 approximation function, designed for sRGB gamma correction. - * - * @param x Argument, in the range 0.09 to 1. - * @return Value raised into power 2.4, approximate. - */ - -template< class T > -inline T pow24_sRGB( const T x ) -{ - const double x2 = (double) x * x; - const double x3 = x2 * x; - const double x4 = x2 * x2; - - return( (T) ( 0.0985766365536824 + 0.839474952656502 * x2 + - 0.363287814061725 * x3 - 0.0125559718896615 / - ( 0.12758338921578 + 0.290283465468235 * x ) - - 0.231757513261358 * x - 0.0395365717969074 * x4 )); -} - -/** - * Power 1/2.4 approximation function, designed for sRGB gamma correction. - * - * @param x Argument, in the range 0.003 to 1. - * @return Value raised into power 1/2.4, approximate. - */ - -template< class T > -inline T pow24i_sRGB( const T x ) -{ - const double sx = sqrt( (double) x ); - const double ssx = sqrt( sx ); - const double sssx = sqrt( ssx ); - - return( (T) ( 0.000213364515060263 + 0.0149409239419218 * x + - 0.433973412731747 * sx + ssx * ( 0.659628181609715 * sssx - - 0.0380957908841466 - 0.0706476137208521 * sx ))); -} - -/** - * Function approximately linearizes the sRGB gamma value. - * - * @param s sRGB gamma value, in the range 0 to 1. - * @return Linearized sRGB gamma value, approximated. - */ - -template< class T > -inline T convertSRGB2Lin( const T s ) -{ - const T a = (T) 0.055; - - if( s <= (T) 0.04045 ) - { - return( s / (T) 12.92 ); - } - - return( pow24_sRGB(( s + a ) / ( (T) 1 + a ))); -} - -/** - * Function approximately de-linearizes the linear gamma value. - * - * @param s Linear gamma value, in the range 0 to 1. - * @return sRGB gamma value, approximated. - */ - -template< class T > -inline T convertLin2SRGB( const T s ) -{ - const T a = (T) 0.055; - - if( s <= (T) 0.0031308 ) - { - return( (T) 12.92 * s ); - } - - return(( (T) 1 + a ) * pow24i_sRGB( s ) - a ); -} - -/** - * Function converts (via typecast) specified array of type T1 values of - * length l into array of type T2 values. If T1 is the same as T2, copy - * operation is performed. When copying data at overlapping address spaces, - * "op" should be lower than "ip". - * - * @param ip Input buffer. - * @param[out] op Output buffer. - * @param l The number of elements to copy. - * @param ip Input buffer pointer increment. - * @param op Output buffer pointer increment. - */ - -template< class T1, class T2 > -inline void copyArray( const T1* ip, T2* op, int l, - const int ipinc = 1, const int opinc = 1 ) -{ - while( l > 0 ) - { - *op = (T2) *ip; - op += opinc; - ip += ipinc; - l--; - } -} - -/** - * Function adds values located in array "ip" to array "op". - * - * @param ip Input buffer. - * @param[out] op Output buffer. - * @param l The number of elements to add. - * @param ip Input buffer pointer increment. - * @param op Output buffer pointer increment. - */ - -template< class T1, class T2 > -inline void addArray( const T1* ip, T2* op, int l, - const int ipinc = 1, const int opinc = 1 ) -{ - while( l > 0 ) - { - *op += *ip; - op += opinc; - ip += ipinc; - l--; - } -} - -/** - * Function that replicates a set of adjacent elements several times in a row. - * This operation is usually used to replicate pixels at the start or end of - * image's scanline. - * - * @param ip Source array. - * @param ipl Source array length (usually 1..4, but can be any number). - * @param[out] op Destination buffer. - * @param l Number of times the source array should be replicated (the - * destination buffer should be able to hold ipl * l number of elements). - * @param opinc Destination buffer position increment after replicating the - * source array. This value should be equal to at least ipl. - */ - -template< class T1, class T2 > -inline void replicateArray( const T1* const ip, const int ipl, T2* op, int l, - const int opinc ) -{ - if( ipl == 1 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op += opinc; - l--; - } - } - else - if( ipl == 4 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op[ 2 ] = (T2) ip[ 2 ]; - op[ 3 ] = (T2) ip[ 3 ]; - op += opinc; - l--; - } - } - else - if( ipl == 3 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op[ 2 ] = (T2) ip[ 2 ]; - op += opinc; - l--; - } - } - else - if( ipl == 2 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op += opinc; - l--; - } - } - else - { - while( l > 0 ) - { - int i; - - for( i = 0; i < ipl; i++ ) - { - op[ i ] = (T2) ip[ i ]; - } - - op += opinc; - l--; - } - } -} - -/** - * Function calculates frequency response of the specified FIR filter at the - * specified circular frequency. Phase can be calculated as atan2( im, re ). - * Function uses computationally-efficient oscillators instead of "cos" and - * "sin" functions. - * - * @param flt FIR filter's coefficients. - * @param fltlen Number of coefficients (taps) in the filter. - * @param th Circular frequency [0; pi]. - * @param[out] re0 Resulting real part of the complex frequency response. - * @param[out] im0 Resulting imaginary part of the complex frequency response. - * @param fltlat Filter's latency in samples (taps). - */ - -template< class T > -inline void calcFIRFilterResponse( const T* flt, int fltlen, - const double th, double& re0, double& im0, const int fltlat = 0 ) -{ - const double sincr = 2.0 * cos( th ); - double cvalue1; - double svalue1; - - if( fltlat == 0 ) - { - cvalue1 = 1.0; - svalue1 = 0.0; - } - else - { - cvalue1 = cos( -fltlat * th ); - svalue1 = sin( -fltlat * th ); - } - - double cvalue2 = cos( -( fltlat + 1 ) * th ); - double svalue2 = sin( -( fltlat + 1 ) * th ); - - double re = 0.0; - double im = 0.0; - - while( fltlen > 0 ) - { - re += cvalue1 * flt[ 0 ]; - im += svalue1 * flt[ 0 ]; - flt++; - fltlen--; - - double tmp = cvalue1; - cvalue1 = sincr * cvalue1 - cvalue2; - cvalue2 = tmp; - - tmp = svalue1; - svalue1 = sincr * svalue1 - svalue2; - svalue2 = tmp; - } - - re0 = re; - im0 = im; -} - -/** - * Function normalizes FIR filter so that its frequency response at DC is - * equal to DCGain. - * - * @param[in,out] p Filter coefficients. - * @param l Filter length. - * @param DCGain Filter's gain at DC. - * @param pstep "p" array step. - */ - -template< class T > -inline void normalizeFIRFilter( T* const p, const int l, const double DCGain, - const int pstep = 1 ) -{ - double s = 0.0; - T* pp = p; - int i = l; - - while( i > 0 ) - { - s += *pp; - pp += pstep; - i--; - } - - s = DCGain / s; - pp = p; - i = l; - - while( i > 0 ) - { - *pp = (T) ( *pp * s ); - pp += pstep; - i--; - } -} - -/** - * @brief Memory buffer class for element array storage, with capacity - * tracking. - * - * Allows easier handling of memory blocks allocation and automatic - * deallocation for arrays (buffers) consisting of elements of specified - * class. Tracks buffer's capacity in "int" variable; unsuitable for - * allocation of very large memory blocks (with more than 2 billion elements). - * - * This class manages memory space only - it does not perform element class - * construction (initialization) operations. Buffer's required memory address - * alignment specification is supported. - * - * Uses standard library to allocate and deallocate memory. - * - * @tparam T Buffer element's type. - * @tparam capint Buffer capacity's type to use. Use size_t for large buffers. - */ - -template< class T, typename capint = int > -class CBuffer -{ -public: - CBuffer() - : Data( NULL ) - , DataAligned( NULL ) - , Capacity( 0 ) - , Alignment( 0 ) - { - } - - /** - * Constructor creates the buffer with the specified capacity. - * - * @param aCapacity Buffer's capacity. - * @param aAlignment Buffer's required memory address alignment. 0 - use - * stdlib's default alignment. - */ - - CBuffer( const capint aCapacity, const int aAlignment = 0 ) - { - allocinit( aCapacity, aAlignment ); - } - - CBuffer( const CBuffer& Source ) - { - allocinit( Source.Capacity, Source.Alignment ); - - if( Capacity > 0 ) - { - memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); - } - } - - ~CBuffer() - { - freeData(); - } - - CBuffer& operator = ( const CBuffer& Source ) - { - alloc( Source.Capacity, Source.Alignment ); - - if( Capacity > 0 ) - { - memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); - } - - return( *this ); - } - - /** - * Function allocates memory so that the specified number of elements - * can be stored in *this buffer object. - * - * @param aCapacity Storage for this number of elements to allocate. - * @param aAlignment Buffer's required memory address alignment, - * power-of-2 values only. 0 - use stdlib's default alignment. - */ - - void alloc( const capint aCapacity, const int aAlignment = 0 ) - { - freeData(); - allocinit( aCapacity, aAlignment ); - } - - /** - * Function deallocates any previously allocated buffer. - */ - - void free() - { - freeData(); - Data = NULL; - DataAligned = NULL; - Capacity = 0; - Alignment = 0; - } - - /** - * @return The capacity of the element buffer. - */ - - capint getCapacity() const - { - return( Capacity ); - } - - /** - * Function "forces" *this buffer to have an arbitary capacity. Calling - * this function invalidates all further operations except deleting *this - * object. This function should not be usually used at all. Function can - * be used to "model" certain buffer capacity without calling a costly - * memory allocation function. - * - * @param NewCapacity A new "forced" capacity. - */ - - void forceCapacity( const capint NewCapacity ) - { - Capacity = NewCapacity; - } - - /** - * Function reallocates *this buffer to a larger size so that it will be - * able to hold the specified number of elements. Downsizing is not - * performed. Alignment is not changed. - * - * @param NewCapacity New (increased) capacity. - * @param DoDataCopy "True" if data in the buffer should be retained. - */ - - void increaseCapacity( const capint NewCapacity, - const bool DoDataCopy = true ) - { - if( NewCapacity < Capacity ) - { - return; - } - - if( DoDataCopy ) - { - const capint PrevCapacity = Capacity; - T* const PrevData = Data; - T* const PrevDataAligned = DataAligned; - - allocinit( NewCapacity, Alignment ); - - if( PrevCapacity > 0 ) - { - memcpy( DataAligned, PrevDataAligned, - PrevCapacity * sizeof( T )); - } - - :: free( PrevData ); - } - else - { - :: free( Data ); - allocinit( NewCapacity, Alignment ); - } - } - - /** - * Function "truncates" (reduces) capacity of the buffer without - * reallocating it. Alignment is not changed. - * - * @param NewCapacity New required capacity. - */ - - void truncateCapacity( const capint NewCapacity ) - { - if( NewCapacity >= Capacity ) - { - return; - } - - Capacity = NewCapacity; - } - - /** - * Function increases capacity so that the specified number of - * elements can be stored. This function increases the previous capacity - * value by third the current capacity value until space for the required - * number of elements is available. Alignment is not changed. - * - * @param ReqCapacity Required capacity. - */ - - void updateCapacity( const capint ReqCapacity ) - { - if( ReqCapacity <= Capacity ) - { - return; - } - - capint NewCapacity = Capacity; - - while( NewCapacity < ReqCapacity ) - { - NewCapacity += NewCapacity / 3 + 1; - } - - increaseCapacity( NewCapacity ); - } - - operator T* () const - { - return( DataAligned ); - } - -private: - T* Data; ///< Element buffer pointer. - ///< - T* DataAligned; ///< Memory address-aligned element buffer pointer. - ///< - capint Capacity; ///< Element buffer capacity. - ///< - int Alignment; ///< Memory address alignment in use. 0 - use stdlib's - ///< default alignment. - ///< - - /** - * Internal element buffer allocation function used during object - * construction. - * - * @param aCapacity Storage for this number of elements to allocate. - * @param aAlignment Buffer's required memory address alignment. 0 - use - * stdlib's default alignment. - */ - - void allocinit( const capint aCapacity, const int aAlignment ) - { - if( aAlignment == 0 ) - { - Data = (T*) :: malloc( aCapacity * sizeof( T )); - DataAligned = Data; - Alignment = 0; - } - else - { - Data = (T*) :: malloc( aCapacity * sizeof( T ) + aAlignment ); - DataAligned = alignptr( Data, aAlignment ); - Alignment = aAlignment; - } - - Capacity = aCapacity; - } - - /** - * Function frees a previously allocated Data buffer. - */ - - void freeData() - { - :: free( Data ); - } - - /** - * Function modifies the specified pointer so that it becomes memory - * address-aligned. - * - * @param ptr Pointer to align. - * @param align Alignment in bytes to apply. - * @return Pointer aligned to align bytes. Works with power-of-2 - * alignments only. If no alignment is necessary, "align" bytes will be - * added to the pointer value. - */ - - template< class Tp > - inline Tp alignptr( const Tp ptr, const uintptr_t align ) - { - return( (Tp) ( (uintptr_t) ptr + align - - ( (uintptr_t) ptr & ( align - 1 ))) ); - } -}; - -/** - * @brief Array of structured objects. - * - * Implements allocation of a linear array of objects of class T (which are - * initialized), addressable via operator[]. Each object is created via the - * "operator new". New object insertions are quick since implementation uses - * prior space allocation (capacity), thus not requiring frequent memory block - * reallocations. - * - * @tparam T Array element's type. - */ - -template< class T > -class CStructArray -{ -public: - CStructArray() - : ItemCount( 0 ) - { - } - - CStructArray( const CStructArray& Source ) - : ItemCount( 0 ) - , Items( Source.getItemCount() ) - { - while( ItemCount < Source.getItemCount() ) - { - Items[ ItemCount ] = new T( Source[ ItemCount ]); - ItemCount++; - } - } - - ~CStructArray() - { - clear(); - } - - CStructArray& operator = ( const CStructArray& Source ) - { - clear(); - - const int NewCount = Source.ItemCount; - Items.updateCapacity( NewCount ); - - while( ItemCount < NewCount ) - { - Items[ ItemCount ] = new T( Source[ ItemCount ]); - ItemCount++; - } - - return( *this ); - } - - T& operator []( const int Index ) - { - return( *Items[ Index ]); - } - - const T& operator []( const int Index ) const - { - return( *Items[ Index ]); - } - - /** - * Function creates a new object of type T with the default constructor - * and adds this object to the array. - * - * @return Reference to a newly added object. - */ - - T& add() - { - if( ItemCount == Items.getCapacity() ) - { - Items.increaseCapacity( ItemCount * 3 / 2 + 1 ); - } - - Items[ ItemCount ] = new T(); - ItemCount++; - - return( (*this)[ ItemCount - 1 ]); - } - - /** - * Function changes number of allocated items. New items are created with - * the default constructor. If NewCount is below the current item count, - * items that are above NewCount range will be destructed. - * - * @param NewCount New requested item count. - */ - - void setItemCount( const int NewCount ) - { - if( NewCount > ItemCount ) - { - Items.increaseCapacity( NewCount ); - - while( ItemCount < NewCount ) - { - Items[ ItemCount ] = new T(); - ItemCount++; - } - } - else - { - while( ItemCount > NewCount ) - { - ItemCount--; - delete Items[ ItemCount ]; - } - } - } - - /** - * Function erases all items of *this array. - */ - - void clear() - { - while( ItemCount > 0 ) - { - ItemCount--; - delete Items[ ItemCount ]; - } - } - - /** - * @return The number of allocated items. - */ - - int getItemCount() const - { - return( ItemCount ); - } - -private: - int ItemCount; ///< The number of items available in the array. - ///< - CBuffer< T* > Items; ///< Element buffer. - ///< -}; - -/** - * @brief Sine signal generator class. - * - * Class implements sine signal generator without biasing, with - * constructor-based initalization only. This generator uses oscillator - * instead of "sin" function. - */ - -class CSineGen -{ -public: - /** - * Constructor initializes *this sine signal generator. - * - * @param si Sine function increment, in radians. - * @param ph Starting phase, in radians. Add 0.5 * AVIR_PI for cosine - * function. - */ - - CSineGen( const double si, const double ph ) - : svalue1( sin( ph )) - , svalue2( sin( ph - si )) - , sincr( 2.0 * cos( si )) - { - } - - /** - * @return The next value of the sine function, without biasing. - */ - - double generate() - { - const double res = svalue1; - - svalue1 = sincr * res - svalue2; - svalue2 = res; - - return( res ); - } - -private: - double svalue1; ///< Current sine value. - ///< - double svalue2; ///< Previous sine value. - ///< - double sincr; ///< Sine value increment. - ///< -}; - -/** - * @brief Peaked Cosine window function generator class. - * - * Class implements Peaked Cosine window function generator. Generates the - * right-handed half of the window function. The Alpha parameter of this - * window function offers the control of the balance between the early and - * later taps of the filter. E.g. at Alpha=1 both early and later taps are - * attenuated, but at Alpha=4 mostly later taps are attenuated. This offers a - * great control over ringing artifacts produced by a low-pass filter in image - * processing, without compromising achieved image sharpness. - */ - -class CDSPWindowGenPeakedCosine -{ -public: - /** - * Constructor initializes *this window function generator. - * - * @param aAlpha Alpha parameter, affects the peak shape (peak - * augmentation) of the window function. Any positive value can be used. - * @param aLen2 Half filter's length (non-truncated). - */ - - CDSPWindowGenPeakedCosine( const double aAlpha, const double aLen2 ) - : Alpha( aAlpha ) - , Len2( aLen2 ) - , Len2i( 1.0 / aLen2 ) - , wn( 0.0 ) - , w1( AVIR_PId2 / Len2, AVIR_PI * 0.5 ) - { - } - - /** - * @return The next Peaked Cosine window function coefficient. - */ - - double generate() - { - const double h = pow( wn * Len2i, Alpha ); - wn += 1.0; - - return( w1.generate() * ( 1.0 - h )); - } - -private: - double Alpha; ///< Alpha parameter, affects the peak shape of window. - ///< - double Len2; ///< Half length of the window function. - ///< - double Len2i; ///< = 1 / Len2. - ///< - double wn; ///< Window function integer position. 0 - center of the - ///< window function. - ///< - CSineGen w1; ///< Sine-wave generator. - ///< -}; - -/** - * @brief FIR filter-based equalizer generator. - * - * Class implements an object used to generate symmetric-odd FIR filters with - * the specified frequency response (aka paragraphic equalizer). The - * calculated filter is windowed by the Peaked Cosine window function. - * - * In image processing, due to short length of filters being used (6-8 taps) - * the resulting frequency response of the filter is approximate and may be - * mathematically imperfect, but still adequate to the visual requirements. - * - * On a side note, this equalizer generator can be successfully used for audio - * signal equalization as well: for example, it is used in almost the same - * form in Voxengo Marvel GEQ equalizer plug-in. - * - * Filter generation is based on decomposition of frequency range into - * spectral bands, with each band represented by linear and ramp "kernels". - * When the filter is built, these kernels are combined together with - * different weights that approximate the required frequency response. - */ - -class CDSPFIREQ -{ -public: - /** - * Function initializes *this object with the required parameters. The - * gain of frequencies beyond the MinFreq..MaxFreq range are controlled by - * the first and the last band's gain. - * - * @param SampleRate Processing sample rate (use 2 for image processing). - * @param aFilterLength Required filter length in samples (taps). The - * actual filter length is truncated to an integer value. - * @param aBandCount Number of band crossover points required to control, - * including bands at MinFreq and MaxFreq. - * @param MinFreq Minimal frequency that should be controlled. - * @param MaxFreq Maximal frequency that should be controlled. - * @param IsLogBands "True" if the bands should be spaced logarithmically. - * @param WFAlpha Peaked Cosine window function's Alpha parameter. - */ - - void init( const double SampleRate, const double aFilterLength, - const int aBandCount, const double MinFreq, const double MaxFreq, - const bool IsLogBands, const double WFAlpha ) - { - FilterLength = aFilterLength; - BandCount = aBandCount; - - CenterFreqs.alloc( BandCount ); - - z = (int) ceil( FilterLength * 0.5 ); - zi = z + ( z & 1 ); - z2 = z * 2; - - CBuffer< double > oscbuf( z2 ); - initOscBuf( oscbuf ); - - CBuffer< double > winbuf( z ); - initWinBuf( winbuf, WFAlpha ); - - UseFirstVirtBand = ( MinFreq > 0.0 ); - const int k = zi * ( BandCount + ( UseFirstVirtBand ? 1 : 0 )); - Kernels1.alloc( k ); - Kernels2.alloc( k ); - - double m; // Frequency step multiplier. - double mo; // Frequency step offset (addition). - - if( IsLogBands ) - { - m = exp( log( MaxFreq / MinFreq ) / ( BandCount - 1 )); - mo = 0.0; - } - else - { - m = 1.0; - mo = ( MaxFreq - MinFreq ) / ( BandCount - 1 ); - } - - double f = MinFreq; - double x1 = 0.0; - double x2; - int si; - - if( UseFirstVirtBand ) - { - si = 0; - } - else - { - si = 1; - CenterFreqs[ 0 ] = 0.0; - f = f * m + mo; - } - - double* kernbuf1 = &Kernels1[ 0 ]; - double* kernbuf2 = &Kernels2[ 0 ]; - int i; - - for( i = si; i < BandCount; i++ ) - { - x2 = f * 2.0 / SampleRate; - CenterFreqs[ i ] = x2; - - fillBandKernel( x1, x2, kernbuf1, kernbuf2, oscbuf, winbuf ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - f = f * m + mo; - } - - if( x1 < 1.0 ) - { - UseLastVirtBand = true; - fillBandKernel( x1, 1.0, kernbuf1, kernbuf2, oscbuf, winbuf ); - } - else - { - UseLastVirtBand = false; - } - } - - /** - * @return Filter's length, in samples (taps). - */ - - int getFilterLength() const - { - return( z2 - 1 ); - } - - /** - * @return Filter's latency (group delay), in samples (taps). - */ - - int getFilterLatency() const - { - return( z - 1 ); - } - - /** - * Function creates symmetric-odd FIR filter with the specified gain - * levels at band crossover points. - * - * @param BandGains Array of linear gain levels, count=BandCount specified - * in the init() function. - * @param[out] Filter Output filter buffer, length = getFilterLength(). - */ - - void buildFilter( const double* const BandGains, double* const Filter ) - { - const double* kernbuf1 = &Kernels1[ 0 ]; - const double* kernbuf2 = &Kernels2[ 0 ]; - double x1 = 0.0; - double y1 = BandGains[ 0 ]; - double x2; - double y2; - - int i; - int si; - - if( UseFirstVirtBand ) - { - si = 1; - x2 = CenterFreqs[ 0 ]; - y2 = y1; - } - else - { - si = 2; - x2 = CenterFreqs[ 1 ]; - y2 = BandGains[ 1 ]; - } - - copyBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - x2 * y1 ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - y1 = y2; - - for( i = si; i < BandCount; i++ ) - { - x2 = CenterFreqs[ i ]; - y2 = BandGains[ i ]; - - addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - x2 * y1 ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - y1 = y2; - } - - if( UseLastVirtBand ) - { - addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - y1 ); - } - - for( i = 0; i < z - 1; i++ ) - { - Filter[ z + i ] = Filter[ z - 2 - i ]; - } - } - - /** - * Function calculates filter's length (in samples) and latency depending - * on the required non-truncated filter length. - * - * @param aFilterLength Required filter length in samples (non-truncated). - * @param[out] Latency Resulting latency (group delay) of the filter, - * in samples (taps). - * @return Filter length in samples (taps). - */ - - static int calcFilterLength( const double aFilterLength, int& Latency ) - { - const int l = (int) ceil( aFilterLength * 0.5 ); - Latency = l - 1; - - return( l * 2 - 1 ); - } - -private: - double FilterLength; ///< Length of filter. - ///< - int z; ///< Equals (int) ceil( FilterLength * 0.5 ). - ///< - int zi; ///< Equals "z" if z is even, or z + 1 if z is odd. Used as a - ///< Kernels1 and Kernels2 size multiplier and kernel buffer increment - ///< to make sure each kernel buffer is 16-byte aligned. - ///< - int z2; ///< Equals z * 2. - ///< - int BandCount; ///< Number of controllable bands. - ///< - CBuffer< double > CenterFreqs; ///< Center frequencies for all bands, - ///< normalized to 0.0-1.0 range. - ///< - CBuffer< double > Kernels1; ///< Half-length kernel buffers for each - ///< spectral band (linear part). - ///< - CBuffer< double > Kernels2; ///< Half-length kernel buffers for each - ///< spectral band (ramp part). - ///< - bool UseFirstVirtBand; ///< "True" if the first virtual band - ///< (between 0.0 and MinFreq) should be used. The first virtual band - ///< won't be used if MinFreq equals 0.0. - ///< - bool UseLastVirtBand; ///< "True" if the last virtual band (between - ///< MaxFreq and SampleRate * 0.5) should be used. The last virtual - ///< band won't be used if MaxFreq * 2.0 equals SampleRate. - ///< - - /** - * Function initializes the "oscbuf" used in the fillBandKernel() - * function. - * - * @param oscbuf Oscillator buffer, length = z * 2. - */ - - void initOscBuf( double* oscbuf ) const - { - int i = z; - - while( i > 0 ) - { - oscbuf[ 0 ] = 0.0; - oscbuf[ 1 ] = 1.0; - oscbuf += 2; - i--; - } - } - - /** - * Function initializes window function buffer. This function generates - * Peaked Cosine window function. - * - * @param winbuf Windowing buffer. - * @param Alpha Peaked Cosine alpha parameter. - */ - - void initWinBuf( double* winbuf, const double Alpha ) const - { - CDSPWindowGenPeakedCosine wf( Alpha, FilterLength * 0.5 ); - int i; - - for( i = 1; i <= z; i++ ) - { - winbuf[ z - i ] = wf.generate(); - } - } - - /** - * Function fills first half of symmetric-odd FIR kernel for the band. - * This function should be called successively for adjacent bands. - * Previous band's x2 should be equal to current band's x1. A band kernel - * consists of 2 elements: linear kernel and ramp kernel. - * - * @param x1 Band's left corner frequency (0..1). - * @param x2 Band's right corner frequency (0..1). - * @param kernbuf1 Band kernel buffer 1 (linear part), length = z. - * @param kernbuf2 Band kernel buffer 2 (ramp part), length = z. - * @param oscbuf Oscillation buffer. Before the first call of the - * fillBandKernel() should be initialized with the call of the - * initOscBuf() function. - * @param winbuf Buffer that contains windowing function. - */ - - void fillBandKernel( const double x1, const double x2, double* kernbuf1, - double* kernbuf2, double* oscbuf, const double* const winbuf ) - { - const double s2_incr = AVIR_PI * x2; - const double s2_coeff = 2.0 * cos( s2_incr ); - - double s2_value1 = sin( s2_incr * ( -z + 1 )); - double c2_value1 = sin( s2_incr * ( -z + 1 ) + AVIR_PI * 0.5 ); - oscbuf[ 0 ] = sin( s2_incr * -z ); - oscbuf[ 1 ] = sin( s2_incr * -z + AVIR_PI * 0.5 ); - - int ks; - - for( ks = 1; ks < z; ks++ ) - { - const int ks2 = ks * 2; - const double s1_value1 = oscbuf[ ks2 ]; - const double c1_value1 = oscbuf[ ks2 + 1 ]; - oscbuf[ ks2 ] = s2_value1; - oscbuf[ ks2 + 1 ] = c2_value1; - - const double x = AVIR_PI * ( ks - z ); - const double v0 = winbuf[ ks - 1 ] / (( x1 - x2 ) * x ); - - kernbuf1[ ks - 1 ] = ( x2 * s2_value1 - x1 * s1_value1 + - ( c2_value1 - c1_value1 ) / x ) * v0; - - kernbuf2[ ks - 1 ] = ( s2_value1 - s1_value1 ) * v0; - - s2_value1 = s2_coeff * s2_value1 - oscbuf[ ks2 - 2 ]; - c2_value1 = s2_coeff * c2_value1 - oscbuf[ ks2 - 1 ]; - } - - kernbuf1[ z - 1 ] = ( x2 * x2 - x1 * x1 ) / ( x1 - x2 ) * 0.5; - kernbuf2[ z - 1 ] = -1.0; - } - - /** - * Function copies band kernel's elements to the output buffer. - * - * @param outbuf Output buffer. - * @param kernbuf1 Kernel buffer 1 (linear part). - * @param kernbuf2 Kernel buffer 2 (ramp part). - * @param c Multiplier for linear kernel element. - * @param d Multiplier for ramp kernel element. - */ - - void copyBandKernel( double* outbuf, const double* const kernbuf1, - const double* const kernbuf2, const double c, const double d ) const - { - int ks; - - for( ks = 0; ks < z; ks++ ) - { - outbuf[ ks ] = c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; - } - } - - /** - * Function adds band kernel's elements to the output buffer. - * - * @param outbuf Output buffer. - * @param kernbuf1 Kernel buffer 1 (linear part). - * @param kernbuf2 Kernel buffer 2 (ramp part). - * @param c Multiplier for linear kernel element. - * @param d Multiplier for ramp kernel element. - */ - - void addBandKernel( double* outbuf, const double* const kernbuf1, - const double* const kernbuf2, const double c, const double d ) const - { - int ks; - - for( ks = 0; ks < z; ks++ ) - { - outbuf[ ks ] += c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; - } - } -}; - -/** - * @brief Low-pass filter windowed by Peaked Cosine window function. - * - * This class implements calculation of linear-phase symmetric-odd FIR - * low-pass filter windowed by the Peaked Cosine window function, for image - * processing applications. - */ - -class CDSPPeakedCosineLPF -{ -public: - int fl2; ///< Half filter's length, excluding the peak value. This value - ///< can be also used as filter's latency in samples (taps). - ///< - int FilterLen; ///< Filter's length in samples (taps). - ///< - - /** - * Constructor initalizes *this object. - * - * @param aLen2 Half-length (non-truncated) of low-pass filter, in samples - * (taps). - * @param aFreq2 Low-pass filter's corner frequency [0; pi]. - * @param aAlpha Peaked Cosine window function Alpha parameter. - */ - - CDSPPeakedCosineLPF( const double aLen2, const double aFreq2, - const double aAlpha ) - : fl2( (int) ceil( aLen2 ) - 1 ) - , FilterLen( fl2 + fl2 + 1 ) - , Len2( aLen2 ) - , Freq2( aFreq2 ) - , Alpha( aAlpha ) - { - } - - /** - * Function generates a linear-phase low-pass filter windowed by Peaked - * Cosine window function. - * - * @param[out] op Output buffer, length = FilterLen (fl2 * 2 + 1). - * @param DCGain Required gain at DC. The resulting filter will be - * normalized to achieve this DC gain. If non-positive, no automatic - * normalization will be performed. - */ - - template< class T > - void generateLPF( T* op, const double DCGain ) - { - CDSPWindowGenPeakedCosine wf( Alpha, Len2 ); - CSineGen f2( Freq2, 0.0 ); - - op += fl2; - T* op2 = op; - f2.generate(); - - if( DCGain > 0.0 ) - { - int t = 1; - - *op = (T) ( Freq2 * wf.generate() ); - double s = *op; - - while( t <= fl2 ) - { - const T v = (T) ( f2.generate() * wf.generate() / t ); - op++; - op2--; - *op = v; - *op2 = v; - s += v + v; - t++; - } - - t = FilterLen; - s = DCGain / s; - - while( t > 0 ) - { - *op2 = (T) ( *op2 * s ); - op2++; - t--; - } - } - else - { - int t = 1; - - *op = (T) ( Freq2 * wf.generate() ); - - while( t <= fl2 ) - { - const T v = (T) ( f2.generate() * wf.generate() / t ); - op++; - op2--; - *op = v; - *op2 = v; - t++; - } - } - } - -private: - double Len2; ///< Half-length (non-truncated) of low-pass filter, in - ///< samples (taps). - ///< - double Freq2; ///< Low-pass filter's corner frequency. - ///< - double Alpha; ///< Peaked Cosine window function Alpha parameter. - ///< -}; - -/** - * @brief Buffer class for parametrized low-pass filter. - * - * This class extends the CBuffer< double > class by adding several variables - * that define a symmetric-odd FIR low-pass filter windowed by Peaked Cosine - * window function. This class can be used to compare filters without - * comparing their buffer contents. - */ - -class CFltBuffer : public CBuffer< double > -{ -public: - double Len2; ///< Half-length (non-truncated) of low-pass filters, in - ///< samples (taps). - ///< - double Freq; ///< Low-pass filter's corner frequency. - ///< - double Alpha; ///< Peaked Cosine window function Alpha parameter. - ///< - double DCGain; ///< DC gain applied to the filter. - ///< - - CFltBuffer() - : CBuffer< double >() - , Len2( 0.0 ) - , Freq( 0.0 ) - , Alpha( 0.0 ) - , DCGain( 0.0 ) - { - } - - /** - * @param b2 Filter buffer to compare *this object to. - * @return Operator returns "true" if both filters have same parameters. - */ - - bool operator == ( const CFltBuffer& b2 ) const - { - return( Len2 == b2.Len2 && Freq == b2.Freq && Alpha == b2.Alpha && - DCGain == b2.DCGain ); - } -}; - -/** - * @brief Sinc function-based fractional delay filter bank. - * - * Class implements storage and initialization of a bank of sinc - * function-based fractional delay filters, expressed as 1st order polynomial - * interpolation coefficients. The filters are produced from a single "long" - * windowed low-pass filter. Also supports 0th-order ("nearest neighbor") - * interpolation. - * - * This class also supports multiplication of each fractional delay filter by - * an external filter (usually a low-pass filter). - * - * @tparam fptype Specifies storage type of the filter coefficients bank. The - * filters are initially calculated using the "double" precision. - */ - -template< class fptype > -class CDSPFracFilterBankLin -{ - AVIR_NOCTOR( CDSPFracFilterBankLin ); - -public: - CDSPFracFilterBankLin() - : Order( -1 ) - { - } - - /** - * Copy constructor copies a limited set of parameters of the source - * filter bank. The actual filters are not copied. Such copying is used - * during filtering steps "modeling" stage. A further init() function - * call is required. - * - * @param s Source filter bank. - */ - - void copyInitParams( const CDSPFracFilterBankLin& s ) - { - WFLen2 = s.WFLen2; - WFFreq = s.WFFreq; - WFAlpha = s.WFAlpha; - FracCount = s.FracCount; - Order = s.Order; - Alignment = s.Alignment; - SrcFilterLen = s.SrcFilterLen; - FilterLen = s.FilterLen; - FilterSize = s.FilterSize; - IsSrcTableBuilt = false; - ExtFilter = s.ExtFilter; - TableFillFlags.alloc( s.TableFillFlags.getCapacity() ); - int i; - - // Copy table fill flags, but shifted so that further initialization - // is still possible (such feature should not be used, though). - - for( i = 0; i < TableFillFlags.getCapacity(); i++ ) - { - TableFillFlags[ i ] = (uint8_t) ( s.TableFillFlags[ i ] << 2 ); - } - } - - /** - * Operator compares *this filter bank and another filter bank and returns - * "true" if their parameters are equal. Alignment is not taken into - * account. - * - * @param s Filter bank to compare to. - * @return "True" if compared banks have equal parameters. - */ - - bool operator == ( const CDSPFracFilterBankLin& s ) const - { - return( Order == s.Order && WFLen2 == s.WFLen2 && - WFFreq == s.WFFreq && WFAlpha == s.WFAlpha && - FracCount == s.FracCount && ExtFilter == s.ExtFilter ); - } - - /** - * Function initializes (builds) the filter bank based on the supplied - * parameters. If the supplied parameters are equal to previously defined - * parameters, function does nothing (alignment is assumed to be never - * changing between the init() function calls). - * - * @param ReqFracCount Required number of fractional delays in the filter - * bank. The minimal value is 2. - * @param ReqOrder Required order of the interpolation polynomial - * (0 or 1). - * @param BaseLen Low-pass filter's base length, in samples (taps). - * Affects the actual length of the filter and its overall steepness. - * @param Cutoff Low-pass filter's normalized cutoff frequency [0; 1]. - * @param aWFAlpha Peaked Cosine window function's Alpha parameter. - * @param aExtFilter External filter to apply to each fractional delay - * filter. - * @param aAlignment Memory alignment of the filter bank, power-of-2 - * value. 0 - use default stdlib alignment. - * @param FltLenAlign Filter's length alignment, power-of-2 value. - */ - - void init( const int ReqFracCount, const int ReqOrder, - const double BaseLen, const double Cutoff, const double aWFAlpha, - const CFltBuffer& aExtFilter, const int aAlignment = 0, - const int FltLenAlign = 1 ) - { - double NewWFLen2 = 0.5 * BaseLen * ReqFracCount; - double NewWFFreq = AVIR_PI * Cutoff / ReqFracCount; - double NewWFAlpha = aWFAlpha; - - if( ReqOrder == Order && NewWFLen2 == WFLen2 && NewWFFreq == WFFreq && - NewWFAlpha == WFAlpha && ReqFracCount == FracCount && - aExtFilter == ExtFilter ) - { - IsInitRequired = false; - return; - } - - WFLen2 = NewWFLen2; - WFFreq = NewWFFreq; - WFAlpha = NewWFAlpha; - FracCount = ReqFracCount; - Order = ReqOrder; - Alignment = aAlignment; - ExtFilter = aExtFilter; - - CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); - SrcFilterLen = ( p.fl2 / ReqFracCount + 1 ) * 2; - - const int ElementSize = ReqOrder + 1; - FilterLen = SrcFilterLen; - - if( ExtFilter.getCapacity() > 0 ) - { - FilterLen += ExtFilter.getCapacity() - 1; - } - - FilterLen = ( FilterLen + FltLenAlign - 1 ) & ~( FltLenAlign - 1 ); - FilterSize = FilterLen * ElementSize; - IsSrcTableBuilt = false; - IsInitRequired = true; - } - - /** - * @return The length of each fractional delay filter, in samples (taps). - * Always an even value. - */ - - int getFilterLen() const - { - return( FilterLen ); - } - - /** - * @return The number of fractional filters in use by *this bank. - */ - - int getFracCount() const - { - return( FracCount ); - } - - /** - * @return The order of the interpolation polynomial. - */ - - int getOrder() const - { - return( Order ); - } - - /** - * Function returns the pointer to the specified interpolation table - * filter. - * - * @param i Filter (fractional delay) index, in the range 0 to - * ReqFracCount - 1, inclusive. - * @return Pointer to filter. Higher order polynomial coefficients are - * stored after after previous order coefficients, separated by FilterLen - * elements. - */ - - const fptype* getFilter( const int i ) - { - if( !IsSrcTableBuilt ) - { - buildSrcTable(); - } - - fptype* const Res = &Table[ i * FilterSize ]; - - if(( TableFillFlags[ i ] & 2 ) == 0 ) - { - createFilter( i ); - TableFillFlags[ i ] |= 2; - - if( Order > 0 ) - { - createFilter( i + 1 ); - const fptype* const Res2 = Res + FilterSize; - fptype* const op = Res + FilterLen; - int j; - - // Create higher-order interpolation coefficients (linear - // interpolation). - - for( j = 0; j < FilterLen; j++ ) - { - op[ j ] = Res2[ j ] - Res[ j ]; - } - } - } - - return( Res ); - } - - /** - * Function makes sure all fractional delay filters were created. - */ - - void createAllFilters() - { - int i; - - for( i = 0; i < FracCount; i++ ) - { - getFilter( i ); - } - } - - /** - * Function returns an approximate initialization complexity, expressed in - * the number of multiply-add operations. This includes fractional delay - * filters calculation and multiplication by an external filter. This - * function can only be called after the init() function. - * - * @param FracUseMap Fractional delays use map, each element corresponds - * to a single fractional delay, will be compared to the internal table - * fill flags. This map should include 0 and 1 values only. - * @return The complexity of the initialization, expressed in the number - * of multiply-add operations. - */ - - int calcInitComplexity( const CBuffer< uint8_t >& FracUseMap ) const - { - const int FltInitCost = 65; // Cost to initialize a single sample - // of the fractional delay filter. - const int FltUseCost = FilterLen * Order + - SrcFilterLen * ExtFilter.getCapacity(); // Cost to use a single - // fractional delay filter. - const int ucb[ 2 ] = { 0, FltUseCost }; - int ic; - int i; - - if( IsInitRequired ) - { - ic = FracCount * SrcFilterLen * FltInitCost; - - for( i = 0; i < FracCount; i++ ) - { - ic += ucb[ FracUseMap[ i ]]; - } - } - else - { - ic = 0; - - for( i = 0; i < FracCount; i++ ) - { - if( FracUseMap[ i ] != 0 ) - { - ic += ucb[ TableFillFlags[ i ] == 0 ? 1 : 0 ]; - } - } - } - - return( ic ); - } - -private: - static const int InterpPoints = 2; ///< The maximal number of points the - ///< interpolation is based on. - ///< - double WFLen2; ///< Window function's Len2 parameter. - ///< - double WFFreq; ///< Window function's Freq parameter. - ///< - double WFAlpha; ///< Window function's Alpha parameter. - ///< - int FracCount; ///< The required number of fractional delay filters. - ///< - int Order; ///< The order of the interpolation polynomial. - ///< - int Alignment; ///< The required filter table alignment. - ///< - int SrcFilterLen; ///< Length of the "source" filters. This is always an - ///< even value. - ///< - int FilterLen; ///< Specifies the number of samples (taps) each fractional - ///< delay filter has. This is always an even value, adjusted by the - ///< FltLenAlign. - ///< - int FilterSize; ///< The size of a single filter element, equals - ///< FilterLen * ElementSize. - ///< - bool IsInitRequired; ///< "True" if SrcTable filter table initialization - ///< is required. This value is available only after the call to the - ///< init() function. - ///< - CBuffer< fptype > Table; ///< Interpolation table, size equals to - ///< ReqFracCount * FilterLen * ElementSize. - ///< - CBuffer< uint8_t > TableFillFlags; ///< Contains ReqFracCount + 1 - ///< elements. Bit 0 of every element is 1 if Table already contains - ///< the filter from SrcTable filtered by ExtFilter. Bit 1 of every - ///< element means higher order coefficients were filled for the - ///< filter. - ///< - CFltBuffer ExtFilter; ///< External filter that should be applied to every - ///< fractional delay filter. Can be empty. Half of this filter's - ///< capacity is used as latency (group delay) value of the filter. - ///< - CBuffer< double > SrcTable; ///< Source table of delay filters, contains - ///< ReqFracCount + 1 elements. This table is used to fill the Table - ///< with the actual filters, filtered by an external filter. - ///< - bool IsSrcTableBuilt; ///< "True" if the SrcTable was built already. This - ///< variable is set to "false" in the init() function. - ///< - - /** - * Function builds source table used in the createFilter() function. - */ - - void buildSrcTable() - { - IsSrcTableBuilt = true; - IsInitRequired = false; - - CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); - - const int BufLen = SrcFilterLen * FracCount + InterpPoints - 1; - const int BufOffs = InterpPoints / 2 - 1; - const int BufCenter = SrcFilterLen * FracCount / 2 + BufOffs; - - CBuffer< double > Buf( BufLen ); - memset( Buf, 0, ( BufCenter - p.fl2 ) * sizeof( double )); - int i = BufLen - BufCenter - p.fl2 - 1; - memset( &Buf[ BufLen - i ], 0, i * sizeof( double )); - - p.generateLPF( &Buf[ BufCenter - p.fl2 ], 0.0 ); - - SrcTable.alloc(( FracCount + 1 ) * SrcFilterLen ); - TableFillFlags.alloc( FracCount + 1 ); - int j; - double* op0 = SrcTable; - - for( i = FracCount; i >= 0; i-- ) - { - TableFillFlags[ i ] = 0; - double* p = Buf + BufOffs + i; - - for( j = 0; j < SrcFilterLen; j++ ) - { - op0[ 0 ] = p[ 0 ]; - op0++; - p += FracCount; - } - - normalizeFIRFilter( op0 - SrcFilterLen, SrcFilterLen, 1.0 ); - } - - Table.alloc(( FracCount + 1 ) * FilterSize, Alignment ); - } - - /** - * Function creates the specified filter in the Table by copying it from - * the SrcTable and filtering by ExtFilter. Function does nothing if - * filter was already created. - * - * @param k Filter index to create, in the range 0 to FracCount, - * inclusive. - */ - - void createFilter( const int k ) - { - if( TableFillFlags[ k ] != 0 ) - { - return; - } - - TableFillFlags[ k ] |= 1; - const int ExtFilterLatency = ExtFilter.getCapacity() / 2; - const int ResLatency = ExtFilterLatency + SrcFilterLen / 2; - int ResLen = SrcFilterLen; - - if( ExtFilter.getCapacity() > 0 ) - { - ResLen += ExtFilter.getCapacity() - 1; - } - - const int ResOffs = FilterLen / 2 - ResLatency; - fptype* op = &Table[ k * FilterSize ]; - int i; - - for( i = 0; i < ResOffs; i++ ) - { - op[ i ] = (fptype) 0; - } - - for( i = ResOffs + ResLen; i < FilterLen; i++ ) - { - op[ i ] = (fptype) 0; - } - - op += ResOffs; - const double* const srcflt = &SrcTable[ k * SrcFilterLen ]; - - if( ExtFilter.getCapacity() == 0 ) - { - for( i = 0; i < ResLen; i++ ) - { - op[ i ] = (fptype) srcflt[ i ]; - } - - return; - } - - // Perform convolution of extflt and srcflt. - - const double* const extflt = &ExtFilter[ 0 ]; - int j; - - for( j = 0; j < ResLen; j++ ) - { - int k = 0; - int l = j - ExtFilter.getCapacity() + 1; - int r = l + ExtFilter.getCapacity(); - - if( l < 0 ) - { - k -= l; - l = 0; - } - - if( r > SrcFilterLen ) - { - r = SrcFilterLen; - } - - const double* const extfltb = extflt + k; - const double* const srcfltb = srcflt + l; - double s = 0.0; - l = r - l; - - for( i = 0; i < l; i++ ) - { - s += extfltb[ i ] * srcfltb[ i ]; - } - - op[ j ] = (fptype) s; - } - } -}; - -/** - * @brief Thread pool for multi-threaded image resizing operation. - * - * This base class is used to organize a multi-threaded image resizing - * operation. The thread pool should consist of threads that initially wait - * for a signal. Upon receiving a signal (via the startAllWorkloads() - * function) each previously added thread should execute its workload's - * process() function once, and return to the wait signal state again. The - * thread pool should be also able to efficiently wait for all workloads to - * finish via the waitAllWorkloadsToFinish() function. - * - * The image resizing algorithm makes calls to functions of this class. - */ - -class CImageResizerThreadPool -{ -public: - CImageResizerThreadPool() - { - } - - virtual ~CImageResizerThreadPool() - { - } - - /** - * @brief Thread pool's workload object class. - * - * This class should be used as a base class for objects that perform the - * actual work spread over several threads. - */ - - class CWorkload - { - public: - virtual ~CWorkload() - { - } - - /** - * Function that gets called from the thread when thread pool's - * startAllWorkloads() function is called. - */ - - virtual void process() = 0; - }; - - /** - * @return The suggested number of workloads (and their associated - * threads) to add. The minimal value this function can return is 1. The - * usual value may depend on the number of physical and virtual cores - * present in the system, and on other considerations. - */ - - virtual int getSuggestedWorkloadCount() const - { - return( 1 ); - } - - /** - * Function adds a new workload (and possibly thread) to the thread pool. - * The caller decides how many parallel workloads (and threads) it - * requires, but this number will not exceed the value returned by the - * getSuggestedWorkloadCount() function. It is implementation-specific how - * many workloads to associate with a single thread. But for efficiency - * reasons each workload should be associated with its own thread. - * - * Note that the same set of workload objects will be processed each time - * the startAllWorkloads() function is called. This means that workload - * objects are added only once. The caller changes the state of the - * workload objects and then calls the startAllWorkloads() function to - * process them. - * - * @param Workload Workload object whose process() function will be called - * from within the thread when the startAllWorkloads() function is called. - */ - - virtual void addWorkload( CWorkload* const Workload ) - { - } - - /** - * Function starts all workloads associated with threads previously added - * via the addWorkload() function. It is assumed that this function - * performs the necessary "memory barrier" (or "cache sync") kind of - * operation so that all threads catch up the prior changes made to the - * workload objects during their wait state. - */ - - virtual void startAllWorkloads() - { - } - - /** - * Function waits for all workloads to finish. - */ - - virtual void waitAllWorkloadsToFinish() - { - } - - /** - * Function removes all workloads previously added via the addWorkload() - * function. This function gets called only after the - * waitAllWorkloadsToFinish() function call. - */ - - virtual void removeAllWorkloads() - { - } -}; - -/** - * @brief Resizing algorithm parameters structure. - * - * This structure holds all selectable parameters used by the resizing - * algorithm at various stages, for both downsizing and upsizing. There are no - * other parameters exist that can optimize the performance of the resizing - * algorithm. Filter length parameters can take fractional values. - * - * Beside quality, these parameters (except Alpha parameters) directly affect - * the computative cost of the resizing algorithm. It is possible to trade - * the visual quality for computative cost. - * - * Anti-alias filtering during downsizing can be defined as a considerable - * reduction of contrast of smallest features of an image. Unfortunately, such - * de-contrasting partially affects features of all sizes thus producing a - * non-linearity of frequency response. All pre-defined parameter sets are - * described by 3 values separated by slashes. The first value is the - * de-contrasting factor of small features (which are being removed) while - * the second value is the de-contrasting factor of large features (which - * should remain intact), with value of 1 equating to "no contrast change". - * The third value is the optimization score (see below), with value of 0 - * equating to the "perfect" linearity of frequency response. - * - * The pre-defined parameter sets offered by this library were auto-optimized - * for the given LPFltBaseLen, IntFltLen and CorrFltAlpha values. The - * optimization goal was to minimize the score: the sum of squares of the - * difference between original and processed images (which was not actually - * resized, k=1). The original image was a 0.5 megapixel uniformly-distributed - * white-noise image with pixel intensities in the 0-1 range. Such goal - * converges very well and produces filtering system with the flattest - * frequency response possible for the given constraints. With this goal, - * increasing the LPFltBaseLen value reduces the general amount of aliasing - * artifacts. - */ - -struct CImageResizerParams -{ - double CorrFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the correction filter. The "usable" values are - ///< in the narrow range 1.0 to 1.5. - ///< - double CorrFltLen; ///< Correction filter's length in samples (taps). The - ///< "usable" range is narrow, 5.5 to 8, as to minimize the - ///< "overcorrection" which is mathematically precise, but visually - ///< unacceptable. - ///< - double IntFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the interpolation low-pass filter. The "usable" - ///< values are in the range 1.5 to 2.5. - ///< - double IntFltCutoff; ///< Interpolation low-pass filter's cutoff frequency - ///< (normalized, [0; 1]). The "usable" range is 0.6 to 0.8. - ///< - double IntFltLen; ///< Interpolation low-pass filter's length in samples - ///< (taps). The length value should be at least 18 or otherwise a - ///< "dark grid" artifact will be introduced if a further sharpening - ///< is applied. IntFltLen together with other IntFlt parameters - ///< should be tuned in a way that produces the flattest frequency - ///< response in 0-0.5 normalized frequency range (this range is due - ///< to 2X upsampling). - ///< - double LPFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the low-pass filter. The "usable" values are - ///< in the range 1.5 to 6.5. - ///< - double LPFltBaseLen; ///< Base length of the low-pass (aka anti-aliasing - ///< or reconstruction) filter, in samples (taps), further adjusted by - ///< the actual cutoff frequency, upsampling and downsampling factors. - ///< The "usable" range is between 6 and 9. - ///< - double LPFltCutoffMult; ///< Low-pass filter's cutoff frequency - ///< multiplier. This value can be both below and above 1.0 as - ///< low-pass filters are inserted on downsampling and upsampling - ///< steps and always have corner frequency equal to or below 0.5pi. - ///< This multiplier shifts low-pass filter's corner frequency towards - ///< lower (if below 1.0) or higher (if above 1.0) frequencies. This - ///< multiplier can be way below 1.0 since any additional - ///< high-frequency damping will be partially corrected by the - ///< correction filter. The "usable" range is 0.3 to 1.0. - ///< - - CImageResizerParams() - : HBFltAlpha( 1.94609 ) - , HBFltCutoff( 0.46437 ) - , HBFltLen( 24 ) - { - } - - double HBFltAlpha; ///< Half-band filter's Alpha. Assigned internally. - ///< - double HBFltCutoff; ///< Half-band filter's cutoff point [0; 1]. Assigned - ///< internally. - ///< - double HBFltLen; ///< Length of the half-band low-pass filter. Assigned - ///< internally. Internally used to perform 2X or higher downsampling. - ///< These filter parameters should be treated as "technical" and do - ///< not require adjustment as they were tuned to suit all - ///< combinations of other parameters. This half-band filter provides - ///< a wide transition band (for minimal ringing artifacts) and a high - ///< stop-band attenuation (for minimal aliasing). - ///< -}; - -/** - * @brief The default set of resizing algorithm parameters - * (10.06/1.88/1.029(256064.90)/0.000039). - * - * This is the default set of resizing parameters that was designed to deliver - * a sharp image while still providing a low amount of ringing artifacts, and - * having a reasonable computational cost. - */ - -struct CImageResizerParamsDef : public CImageResizerParams -{ - CImageResizerParamsDef() - { - CorrFltAlpha = 0.97946;//10.06/1.88/1.029(256064.90)/0.000039:258649,447179 - CorrFltLen = 6.4262; - IntFltAlpha = 6.41341; - IntFltCutoff = 0.7372; - IntFltLen = 18; - LPFltAlpha = 4.76449; - LPFltBaseLen = 7.55999999999998; - LPFltCutoffMult = 0.79285; - } -}; - -/** - * @brief Set of resizing algorithm parameters for ultra-low-ringing - * performance (7.50/2.01/1.083(11568559.86)/0.000001). - * - * This set of resizing algorithm parameters offers the lowest amount of - * ringing this library is capable of providing while still offering a decent - * quality. Low ringing is attained at the expense of higher aliasing - * artifacts and a slightly reduced contrast. - */ - -struct CImageResizerParamsULR : public CImageResizerParams -{ - CImageResizerParamsULR() - { - CorrFltAlpha = 0.95521;//7.50/2.01/1.083(11568559.86)/0.000001:258649,434609 - CorrFltLen = 5.70774; - IntFltAlpha = 1.00766; - IntFltCutoff = 0.74202; - IntFltLen = 18; - LPFltAlpha = 1.6801; - LPFltBaseLen = 6.62; - LPFltCutoffMult = 0.67821; - } -}; - -/** - * @brief Set of resizing algorithm parameters for low-ringing performance - * (7.91/1.96/1.065(1980857.66)/0.000004). - * - * This set of resizing algorithm parameters offers a very low-ringing - * performance at the expense of higher aliasing artifacts and a slightly - * reduced contrast. - */ - -struct CImageResizerParamsLR : public CImageResizerParams -{ - CImageResizerParamsLR() - { - CorrFltAlpha = 1;//7.91/1.96/1.065(1980857.66)/0.000004:258649,437578 - CorrFltLen = 5.865; - IntFltAlpha = 1.79529; - IntFltCutoff = 0.74325; - IntFltLen = 18; - LPFltAlpha = 1.87597; - LPFltBaseLen = 6.89999999999999; - LPFltCutoffMult = 0.69326; - } -}; - -/** - * @brief Set of resizing algorithm parameters for lower-ringing performance - * (9.21/1.91/1.040(391960.71)/0.000023). - * - * This set of resizing algorithm parameters offers a lower-ringing - * performance in comparison to the default setting, at the expense of higher - * aliasing artifacts and a slightly reduced contrast. - */ - -struct CImageResizerParamsLow : public CImageResizerParams -{ - CImageResizerParamsLow() - { - CorrFltAlpha = 0.99739;//9.21/1.91/1.040(391960.71)/0.000023:258649,444105 - CorrFltLen = 6.20326; - IntFltAlpha = 4.6836; - IntFltCutoff = 0.73879; - IntFltLen = 18; - LPFltAlpha = 7.86565; - LPFltBaseLen = 6.91999999999999; - LPFltCutoffMult = 0.78379; - } -}; - -/** - * @brief Set of resizing algorithm parameters for low-aliasing - * resizing (11.59/1.84/1.015(73054.59)/0.000159). - * - * This set of resizing algorithm parameters offers a considerable - * anti-aliasing performance with a good frequency response linearity (and - * contrast). This is an intermediate setting between the default and Ultra - * parameters. - */ - -struct CImageResizerParamsHigh : public CImageResizerParams -{ - CImageResizerParamsHigh() - { - CorrFltAlpha = 0.97433;//11.59/1.84/1.015(73054.59)/0.000159:258649,451830 - CorrFltLen = 6.87893; - IntFltAlpha = 7.74731; - IntFltCutoff = 0.73844; - IntFltLen = 18; - LPFltAlpha = 4.8149; - LPFltBaseLen = 8.07999999999996; - LPFltCutoffMult = 0.79335; - } -}; - -/** - * @brief Set of resizing algorithm parameters for ultra low-aliasing - * resizing (13.68/1.79/1.000(521792.07)/0.000026). - * - * This set of resizing algorithm parameters offers a very considerable - * anti-aliasing performance with a good frequency response linearity (and - * contrast). This set of parameters is computationally expensive and may - * produce ringing artifacts on sharp features. - */ - -struct CImageResizerParamsUltra : public CImageResizerParams -{ - CImageResizerParamsUltra() - { - CorrFltAlpha = 0.99705;//13.68/1.79/1.000(521792.07)/0.000026:258649,457973 - CorrFltLen = 7.42695; - IntFltAlpha = 1.71985; - IntFltCutoff = 0.7571; - IntFltLen = 18; - LPFltAlpha = 6.71313; - LPFltBaseLen = 8.27999999999996; - LPFltCutoffMult = 0.78413; - } -}; - -/** - * @brief Image resizing variables class. - * - * This is an utility "catch all" class that defines various variables used - * during image resizing. Several variables that are explicitly initialized in - * this class' constructor are also used as additional "input" variables to - * the image resizing function. These variables will not be changed by the - * avir::CImageResizer<>::resizeImage() function. - */ - -class CImageResizerVars -{ -public: - int ElCount; ///< The number of "fptype" elements used to store 1 pixel. - ///< - int ElCountIO; ///< The number of source and destination image's elements - ///< used to store 1 pixel. - ///< - int fppack; ///< The number of atomic types stored in a single "fptype" - ///< element. - ///< - int fpalign; ///< Suggested alignment size in bytes. This is not a - ///< required alignment, because image resizing algorithm cannot be - ///< made to have a strictly aligned data access in all cases (e.g. - ///< de-interleaved interpolation cannot perform aligned accesses). - ///< - int elalign; ///< Length alignment of arrays of elements. This applies to - ///< filters and intermediate buffers: this constant forces filters - ///< and scanlines to have a length which is a multiple of this value, - ///< for more efficient SIMD implementation. - ///< - int packmode; ///< 0 if interleaved packing, 1 if de-interleaved. - ///< - int BufLen[ 2 ]; ///< Intermediate buffers' lengths in "fptype" elements. - int BufOffs[ 2 ]; ///< Offsets into the intermediate buffers, used to - ///< provide prefix elements required during processing so that no - ///< "out of range" access happens. This offset is a multiple of - ///< ElCount if pixels are stored in interleaved form. - ///< - double k; ///< Resizing step coefficient, updated to reflect the actually - ///< used coefficient during resizing. - ///< - double o; ///< Starting pixel offset inside the source image, updated to - ///< reflect the actually used offset during resizing. - ///< - int ResizeStep; ///< Index of the resizing step in the latest filtering - ///< steps array. - ///< - bool IsResize2; ///< Use optimized "doResize2" function. - ///< - double InGammaMult; ///< Input gamma multiplier, used to convert input - ///< data to 0 to 1 range. 0.0 if no gamma is in use. - ///< - double OutGammaMult; ///< Output gamma multiplier, used to convert data to - ///< 0 to 255/65535 range. 0.0 if no gamma is in use. - ///< - - double ox; ///< Start X pixel offset within source image (can be - ///< negative). Positive offset moves image to the left. - ///< - double oy; ///< Start Y pixel offset within source image (can be - ///< negative). Positive offset moves image to the top. - ///< - CImageResizerThreadPool* ThreadPool; ///< Thread pool to be used by the - ///< image resizing function. Set to NULL to use single-threaded - ///< processing. - ///< - bool UseSRGBGamma; ///< Perform sRGB gamma linearization (correction). - ///< - int BuildMode; ///< The build mode to use, for debugging purposes. Set to - ///< -1 to select a minimal-complexity mode automatically. All build - ///< modes deliver similar results with minor deviations. - ///< - int RndSeed; ///< Random seed parameter. This parameter may be incremented - ///< after each random generator initialization. The use of this - ///< variable depends on the ditherer implementation. - ///< - - CImageResizerVars() - : ox( 0.0 ) - , oy( 0.0 ) - , ThreadPool( NULL ) - , UseSRGBGamma( false ) - , BuildMode( -1 ) - , RndSeed( 0 ) - { - } -}; - -/** - * @brief Image resizer's filtering step class. - * - * Class defines data to perform a single filtering step over a whole - * horizontal or vertical scanline. Resizing consists of 1 or more steps that - * may be performed before the actual resizing takes place. Filtering may also - * follow a resizing step. Each step must ensure that scanline data contains - * enough pixels to perform the next step (which may be resizing) without - * exceeding scanline's bounds. - * - * A derived class must implement several "const" and "static" functions that - * are used to perform the actual filtering in interleaved or de-interleaved - * mode. - * - * @tparam fptype Floating point type to use for storing pixel elements. SIMD - * types can be used: in this case each element may hold a whole pixel. - * @tparam fptypeatom The atomic type the "fptype" consists of. - */ - -template< class fptype, class fptypeatom > -class CImageResizerFilterStep -{ - AVIR_NOCTOR( CImageResizerFilterStep ); - -public: - bool IsUpsample; ///< "True" if this step is an upsampling step, "false" - ///< if downsampling step. Should be set to "false" if ResampleFactor - ///< equals 0. - ///< - int ResampleFactor; ///< Resample factor (>=1). If 0, this is a resizing - ///< step. This value should be >1 if IsUpsample equals "true". - ///< - CBuffer< fptype > Flt; ///< Filter to use at this step. - ///< - CFltBuffer FltOrig; ///< Originally-designed filter. This buffer may not - ///< be assigned. Assigned by filters that precede the resizing step - ///< if such filter is planned to be embedded into the interpolation - ///< filter as "external" filter. If IsUpsample=true and this filter - ///< buffer is not empty, the upsampling step will not itself apply - ///< any filtering over upsampled input scanline. - ///< - double DCGain; ///< DC gain which was applied to the filter. Not defined - ///< if ResampleFactor = 0. - ///< - int FltLatency; ///< Filter's latency (group delay, shift) in pixels. - ///< - const CImageResizerVars* Vars; ///< Image resizing-related variables. - ///< - int InLen; ///< Input scanline's length in pixels. - ///< - int InBuf; ///< Input buffer index, 0 or 1. - ///< - int InPrefix; ///< Required input prefix pixels. These prefix pixels will - ///< be filled with source scanline's first pixel value. If IsUpsample - ///< is "true", this is the additional number of times the first pixel - ///< will be filtered before processing scanline, this number is also - ///< reflected in the OutPrefix. - ///< - int InSuffix; ///< Required input suffix pixels. These suffix pixels will - ///< be filled with source scanline's last pixel value. If IsUpsample - ///< is "true", this is the additional number of times the last pixel - ///< will be filtered before processing scanline, this number is also - ///< reflected in the OutSuffix. - ///< - int InElIncr; ///< Pixel element increment within the input buffer, used - ///< during de-interleaved processing: in this case each image's - ///< channel is stored independently, InElIncr elements apart. - ///< - int OutLen; ///< Length of the resulting scanline. - ///< - int OutBuf; ///< Output buffer index. 0 or 1; 2 for the last step. - ///< - int OutPrefix; ///< Required output prefix pixels. These prefix pixels - ///< will not be pre-filled with any values. Value is valid only if - ///< IsUpsample equals "true". - ///< - int OutSuffix; ///< Required input suffix pixels. These suffix pixels will - ///< not be pre-filled with any values. Value is valid only if - ///< IsUpsample equals "true". - ///< - int OutElIncr; ///< Pixel element increment within the output buffer, used - ///< during de-interleaved processing. Equals to the InBufElIncr of - ///< the next step. - ///< - CBuffer< fptype > PrefixDC; ///< DC component fluctuations added at the - ///< start of the resulting scanline, used when IsUpsample equals - ///< "true". - ///< - CBuffer< fptype > SuffixDC; ///< DC component fluctuations added at the - ///< end of the resulting scanline, used when IsUpsample equals - ///< "true". - ///< - int EdgePixelCount; ///< The number of edge pixels added. Affects the - ///< initial position within the input scanline, used to produce edge - ///< pixels. This variable is used and should be defined when - ///< IsUpsample=false and ResampleFactor>0. When assigning this - ///< variable it is also necessary to update InPrefix, OutLen and - ///< Vars.o variables. - ///< - static const int EdgePixelCountDef = 3; ///< The default number of pixels - ///< additionally produced at scanline edges during filtering. This is - ///< required to reduce edge artifacts. - ///< - - /** - * @brief Resizing position structure. - * - * Structure holds resizing position and pointer to fractional delay - * filter. - */ - - struct CResizePos - { - int SrcPosInt; ///< Source scanline position. - ///< - int fti; ///< Fractional delay filter index. - ///< - const fptype* ftp; ///< Fractional delay filter pointer. - ///< - fptypeatom x; ///< Interpolation coefficient between delay filters. - ///< - int SrcOffs; ///< Source scanline offset. - ///< - int fl; ///< Filter length to use, applies to doResize2() only. - ///< - }; - - /** - * @brief Resizing positions buffer class. - * - * This class combines buffer together with variables that define resizing - * stepping. - */ - - class CRPosBuf : public CBuffer< CResizePos > - { - public: - double k; ///< Resizing step. - ///< - double o; ///< Resizing offset. - ///< - int FracCount; ///< The number of fractional delay filters in a filter - ///< bank used together with this buffer. - ///< - }; - - /** - * @brief Resizing positions buffer array class. - * - * This class combines structure array of the CRPosBuf class objects with - * the function that locates or creates buffer with the required resizing - * stepping. - */ - - class CRPosBufArray : public CStructArray< CRPosBuf > - { - public: - using CStructArray< CRPosBuf > :: add; - using CStructArray< CRPosBuf > :: getItemCount; - - /** - * Function returns the resizing positions buffer with the required - * stepping. If no such buffer exists, it is created. - * - * @param k Resizing step. - * @param o Resizing offset. - * @param FracCount The number of fractional delay filters in a filter - * bank used together with this buffer. - * @return Reference to the CRPosBuf object. - */ - - CRPosBuf& getRPosBuf( const double k, const double o, - const int FracCount ) - { - int i; - - for( i = 0; i < getItemCount(); i++ ) - { - CRPosBuf& Buf = (*this)[ i ]; - - if( Buf.k == k && Buf.o == o && Buf.FracCount == FracCount ) - { - return( Buf ); - } - } - - CRPosBuf& NewBuf = add(); - NewBuf.k = k; - NewBuf.o = o; - NewBuf.FracCount = FracCount; - - return( NewBuf ); - } - }; - - CRPosBuf* RPosBuf; ///< Resizing positions buffer. Used when - ///< ResampleFactor equals 0 (resizing step). - ///< - CDSPFracFilterBankLin< fptype >* FltBank; ///< Filter bank in use by *this - ///< resizing step. - ///< - - CImageResizerFilterStep() - { - } -}; - -/** - * @brief Interleaved filtering steps implementation class. - * - * This class implements scanline filtering functions in interleaved mode. - * This means that each pixel is processed independently, not in groups. - * - * @tparam fptype Floating point type to use for storing pixel elements. SIMD - * types can be used: in this case each element may hold a whole pixel. - * @tparam fptypeatom The atomic type the "fptype" consists of. - */ - -template< class fptype, class fptypeatom > -class CImageResizerFilterStepINL : - public CImageResizerFilterStep< fptype, fptypeatom > -{ -public: - using CImageResizerFilterStep< fptype, fptypeatom > :: IsUpsample; - using CImageResizerFilterStep< fptype, fptypeatom > :: ResampleFactor; - using CImageResizerFilterStep< fptype, fptypeatom > :: Flt; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltOrig; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltLatency; - using CImageResizerFilterStep< fptype, fptypeatom > :: Vars; - using CImageResizerFilterStep< fptype, fptypeatom > :: InLen; - using CImageResizerFilterStep< fptype, fptypeatom > :: InPrefix; - using CImageResizerFilterStep< fptype, fptypeatom > :: InSuffix; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutLen; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutPrefix; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutSuffix; - using CImageResizerFilterStep< fptype, fptypeatom > :: PrefixDC; - using CImageResizerFilterStep< fptype, fptypeatom > :: SuffixDC; - using CImageResizerFilterStep< fptype, fptypeatom > :: RPosBuf; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltBank; - using CImageResizerFilterStep< fptype, fptypeatom > :: EdgePixelCount; - - /** - * Function performs "packing" of a scanline, and type conversion. - * Scanline, depending on the "fptype" can be potentially stored as a - * packed SIMD values having a certain atomic type. If required, the sRGB - * gamma correction is applied. - * - * @param ip Input scanline. - * @param op0 Output scanline. - * @param l0 The number of pixels to "pack". - */ - - template< class Tin > - void packScanline( const Tin* ip, fptype* const op0, const int l0 ) const - { - const int ElCount = Vars -> ElCount; - const int ElCountIO = Vars -> ElCountIO; - fptype* op = op0; - int l = l0; - - if( !Vars -> UseSRGBGamma ) - { - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - op += ElCount; - ip++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - v[ 2 ] = (fptypeatom) ip[ 2 ]; - v[ 3 ] = (fptypeatom) ip[ 3 ]; - op += ElCount; - ip += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - v[ 2 ] = (fptypeatom) ip[ 2 ]; - op += ElCount; - ip += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - op += ElCount; - ip += 2; - l--; - } - } - } - else - { - const fptypeatom gm = (fptypeatom) Vars -> InGammaMult; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - op += ElCount; - ip++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); - v[ 3 ] = convertSRGB2Lin( (fptypeatom) ip[ 3 ] * gm ); - op += ElCount; - ip += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); - op += ElCount; - ip += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - op += ElCount; - ip += 2; - l--; - } - } - } - - const int ZeroCount = ElCount * Vars -> fppack - ElCountIO; - op = (fptype*) ( (fptypeatom*) op0 + ElCountIO ); - l = l0; - - if( ZeroCount == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - else - if( ZeroCount == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - v[ 1 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - else - if( ZeroCount == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - v[ 1 ] = (fptypeatom) 0; - v[ 2 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - } - - /** - * Function applies Linear to sRGB gamma correction to the specified - * scanline. - * - * @param p Scanline. - * @param l The number of pixels to de-linearize. - * @param Vars0 Image resizing-related variables. - */ - - static void applySRGBGamma( fptype* p, int l, - const CImageResizerVars& Vars0 ) - { - const int ElCount = Vars0.ElCount; - const int ElCountIO = Vars0.ElCountIO; - const fptypeatom gm = (fptypeatom) Vars0.OutGammaMult; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; - v[ 3 ] = convertLin2SRGB( v[ 3 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - p += ElCount; - l--; - } - } - } - - /** - * Function converts vertical scanline to horizontal scanline. This - * function is called by the image resizer when image is resized - * vertically. This means that the vertical scanline is stored in the - * same format produced by the packScanline() and maintained by other - * filtering functions. - * - * @param ip Input vertical scanline. - * @param op Output buffer (temporary buffer used during resizing). - * @param SrcLen The number of pixels in the input scanline, also used to - * calculate input buffer increment. - * @param SrcIncr Input buffer increment to the next vertical pixel. - */ - - void convertVtoH( const fptype* ip, fptype* op, const int SrcLen, - const int SrcIncr ) const - { - const int ElCount = Vars -> ElCount; - int j; - - if( ElCount == 1 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - ip += SrcIncr; - op++; - } - } - else - if( ElCount == 4 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - op[ 2 ] = ip[ 2 ]; - op[ 3 ] = ip[ 3 ]; - ip += SrcIncr; - op += 4; - } - } - else - if( ElCount == 3 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - op[ 2 ] = ip[ 2 ]; - ip += SrcIncr; - op += 3; - } - } - else - if( ElCount == 2 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - ip += SrcIncr; - op += 2; - } - } - } - - /** - * Function performs "unpacking" of a scanline and type conversion - * (truncation is used when floating point is converted to integer). - * Scanline, depending on the "fptype" can be potentially stored as a - * packed SIMD values having a certain atomic type. The unpacking function - * assumes that scanline is stored in the style produced by the - * packScanline() function. - * - * @param ip Input scanline. - * @param op Output scanline. - * @param l The number of pixels to "unpack". - * @param Vars0 Image resizing-related variables. - */ - - template< class Tout > - static void unpackScanline( const fptype* ip, Tout* op, int l, - const CImageResizerVars& Vars0 ) - { - const int ElCount = Vars0.ElCount; - const int ElCountIO = Vars0.ElCountIO; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - ip += ElCount; - op++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - op[ 2 ] = (Tout) v[ 2 ]; - op[ 3 ] = (Tout) v[ 3 ]; - ip += ElCount; - op += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - op[ 2 ] = (Tout) v[ 2 ]; - ip += ElCount; - op += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - ip += ElCount; - op += 2; - l--; - } - } - } - - /** - * Function calculates scanline's DC gain for each channel, further used - * to "unbias" the scanline. - * - * @param p Source scanline. - * @param SrcLen Source scanline's length. - * @param[out] ElBiases Resuling biases. - */ - - void calcScanlineBias( const fptype* p, const int SrcLen, - fptype* const ElBiases ) const - { - const int ElCount = Vars -> ElCount; - int l = SrcLen; - - if( ElCount == 1 ) - { - fptype b0 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - p++; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - } - else - if( ElCount == 4 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - fptype b2 = (fptype) 0; - fptype b3 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - b2 += p[ 2 ]; - b3 += p[ 3 ]; - p += 4; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - ElBiases[ 2 ] = b2 / (fptype) SrcLen; - ElBiases[ 3 ] = b3 / (fptype) SrcLen; - } - else - if( ElCount == 3 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - fptype b2 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - b2 += p[ 2 ]; - p += 3; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - ElBiases[ 2 ] = b2 / (fptype) SrcLen; - } - else - if( ElCount == 2 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - p += 2; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - } - } - - /** - * Function applies "unbiasing" to the scanline, by subtracting the - * previously calculated bias (DC gain) values. - * - * @param p Scanline. - * @param l Scanline's length. - * @param ElBiases Biases to subtract, for each channel. - */ - - void unbiasScanline( fptype* p, int l, - const fptype* const ElBiases ) const - { - const int ElCount = Vars -> ElCount; - - if( ElCount == 1 ) - { - const fptype b0 = ElBiases[ 0 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p++; - l--; - } - } - else - if( ElCount == 4 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - const fptype b2 = ElBiases[ 2 ]; - const fptype b3 = ElBiases[ 3 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p[ 2 ] -= b2; - p[ 3 ] -= b3; - p += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - const fptype b2 = ElBiases[ 2 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p[ 2 ] -= b2; - p += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p += 2; - l--; - } - } - } - - /** - * Function prepares input scanline buffer for *this filtering step. - * Left- and right-most pixels are replicated to make sure no buffer - * overrun happens. Such approach also allows to bypass any pointer - * range checks. - * - * @param Src Source buffer. - */ - - void prepareInBuf( fptype* Src ) const - { - if( IsUpsample || InPrefix + InSuffix == 0 ) - { - return; - } - - const int ElCount = Vars -> ElCount; - replicateArray( Src, ElCount, Src - ElCount, InPrefix, -ElCount ); - - Src += ( InLen - 1 ) * ElCount; - replicateArray( Src, ElCount, Src + ElCount, InSuffix, ElCount ); - } - - /** - * Function peforms scanline upsampling with filtering. - * - * @param Src Source scanline buffer (length = this -> InLen). Source - * scanline increment will be equal to ElCount. - * @param Dst Destination scanline buffer. - */ - - void doUpsample( const fptype* const Src, fptype* const Dst ) const - { - const int ElCount = Vars -> ElCount; - fptype* op0 = &Dst[ -OutPrefix * ElCount ]; - memset( op0, 0, ( OutPrefix + OutLen + OutSuffix ) * ElCount * - sizeof( fptype )); - - const fptype* ip = Src; - const int opstep = ElCount * ResampleFactor; - int l; - - if( FltOrig.getCapacity() > 0 ) - { - // Do not perform filtering, only upsample. - - op0 += ( OutPrefix % ResampleFactor ) * ElCount; - l = OutPrefix / ResampleFactor; - - if( ElCount == 1 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - l--; - } - } - - return; - } - - const fptype* const f = Flt; - const int flen = Flt.getCapacity(); - fptype* op; - int i; - - if( ElCount == 1 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 4 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 3 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 2 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - op0 += opstep; - l--; - } - } - - op = op0; - const fptype* dc = SuffixDC; - l = SuffixDC.getCapacity(); - - if( ElCount == 1 ) - { - for( i = 0; i < l; i++ ) - { - op[ i ] += ip[ 0 ] * dc[ i ]; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - op[ 3 ] += ip[ 3 ] * dc[ 0 ]; - dc++; - op += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - dc++; - op += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - dc++; - op += 2; - l--; - } - } - - ip = Src; - op = Dst - InPrefix * opstep; - dc = PrefixDC; - l = PrefixDC.getCapacity(); - - if( ElCount == 1 ) - { - for( i = 0; i < l; i++ ) - { - op[ i ] += ip[ 0 ] * dc[ i ]; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - op[ 3 ] += ip[ 3 ] * dc[ 0 ]; - dc++; - op += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - dc++; - op += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - dc++; - op += 2; - l--; - } - } - } - - /** - * Function peforms scanline filtering with optional downsampling. - * Function makes use of the symmetry of the filter. - * - * @param Src Source scanline buffer (length = this -> InLen). Source - * scanline increment will be equal to ElCount. - * @param Dst Destination scanline buffer. - * @param DstIncr Destination scanline buffer increment, used for - * horizontal or vertical scanline stepping. - */ - - void doFilter( const fptype* const Src, fptype* Dst, - const int DstIncr ) const - { - const int ElCount = Vars -> ElCount; - const fptype* const f = &Flt[ FltLatency ]; - const int flen = FltLatency + 1; - const int ipstep = ElCount * ResampleFactor; - const fptype* ip = Src - EdgePixelCount * ipstep; - const fptype* ip1; - const fptype* ip2; - int l = OutLen; - int i; - - if( ElCount == 1 ) - { - while( l > 0 ) - { - fptype s = f[ 0 ] * ip[ 0 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1++; - ip2--; - s += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - } - - Dst[ 0 ] = s; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - fptype s3 = f[ 0 ] * ip[ 2 ]; - fptype s4 = f[ 0 ] * ip[ 3 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 4; - ip2 -= 4; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); - s4 += f[ i ] * ( ip1[ 3 ] + ip2[ 3 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst[ 2 ] = s3; - Dst[ 3 ] = s4; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - fptype s3 = f[ 0 ] * ip[ 2 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 3; - ip2 -= 3; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst[ 2 ] = s3; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 2; - ip2 -= 2; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - } - - /** - * Function performs resizing of a single scanline. This function does - * not "know" about the length of the source scanline buffer. This buffer - * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is - * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) - * does not exceed source scanline's buffer length. SrcLine's increment is - * assumed to be equal to ElCount. - * - * @param SrcLine Source scanline buffer. - * @param DstLine Destination (resized) scanline buffer. - * @param DstLineIncr Destination scanline position increment, used for - * horizontal or vertical scanline stepping. - * @param ElBiases Bias values to add to the resulting scanline. - * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be - * aligned by fpclass :: fpalign. - */ - - void doResize( const fptype* SrcLine, fptype* DstLine, - const int DstLineIncr, const fptype* const ElBiases, - fptype* const ) const - { - const int IntFltLen = FltBank -> getFilterLen(); - const int ElCount = Vars -> ElCount; - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* rpos = &(*RPosBuf)[ 0 ]; - - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* const rpose = rpos + OutLen; - -#define AVIR_RESIZE_PART1 \ - while( rpos < rpose ) \ - { \ - const fptype x = (fptype) rpos -> x; \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* const ftp2 = ftp + IntFltLen; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - int i; - -#define AVIR_RESIZE_PART1nx \ - while( rpos < rpose ) \ - { \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - int i; - -#define AVIR_RESIZE_PART2 \ - DstLine += DstLineIncr; \ - rpos++; \ - } - - if( FltBank -> getOrder() == 1 ) - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - sum0 += ( ftp[ i ] + ftp2[ i ] * x ) * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - else - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - sum0 += ftp[ i ] * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - } -#undef AVIR_RESIZE_PART2 -#undef AVIR_RESIZE_PART1nx -#undef AVIR_RESIZE_PART1 - - /** - * Function performs resizing of a single scanline assuming that the input - * buffer consists of zero-padded elements (2X upsampling without - * filtering). Similar to the doResize() function otherwise. - * - * @param SrcLine Source scanline buffer. - * @param DstLine Destination (resized) scanline buffer. - * @param DstLineIncr Destination scanline position increment, used for - * horizontal or vertical scanline stepping. - * @param ElBiases Bias values to add to the resulting scanline. - * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be - * aligned by fpclass :: fpalign. - */ - - void doResize2( const fptype* SrcLine, fptype* DstLine, - const int DstLineIncr, const fptype* const ElBiases, - fptype* const ) const - { - const int IntFltLen0 = FltBank -> getFilterLen(); - const int ElCount = Vars -> ElCount; - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* rpos = &(*RPosBuf)[ 0 ]; - - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* const rpose = rpos + OutLen; - -#define AVIR_RESIZE_PART1 \ - while( rpos < rpose ) \ - { \ - const fptype x = (fptype) rpos -> x; \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* const ftp2 = ftp + IntFltLen0; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - const int IntFltLen = rpos -> fl; \ - int i; - -#define AVIR_RESIZE_PART1nx \ - while( rpos < rpose ) \ - { \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - const int IntFltLen = rpos -> fl; \ - int i; - -#define AVIR_RESIZE_PART2 \ - DstLine += DstLineIncr; \ - rpos++; \ - } - - if( FltBank -> getOrder() == 1 ) - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - sum0 += ( ftp[ i ] + ftp2[ i ] * x ) * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - else - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - sum0 += ftp[ i ] * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - } -#undef AVIR_RESIZE_PART2 -#undef AVIR_RESIZE_PART1nx -#undef AVIR_RESIZE_PART1 -}; - -/** - * @brief Image resizer's default dithering class. - * - * This class defines an object that performs rounding, clipping and dithering - * operations over horizontal scanline pixels before scanline is stored in the - * output buffer. - * - * The ditherer should expect the same storage order of the pixels in a - * scanline as used in the "filtering step" class. So, a separate ditherer - * class should be defined for each scanline pixel storage style. The default - * ditherer implements a simple rounding without dithering: it can be used for - * an efficient dithering method which can be multi-threaded. - * - * @tparam fptype Floating point type to use for storing pixel data. SIMD - * types can be used. - */ - -template< class fptype > -class CImageResizerDithererDefINL -{ -public: - /** - * Function initializes the ditherer object. - * - * @param aLen Scanline length in pixels to process. - * @param aVars Image resizing-related variables. - * @param aTrMul Bit-depth truncation multiplier. 1 - no additional - * truncation. - * @param aPkOut Peak output value allowed. - */ - - void init( const int aLen, const CImageResizerVars& aVars, - const double aTrMul, const double aPkOut ) - { - Len = aLen; - Vars = &aVars; - LenE = aLen * Vars -> ElCount; - TrMul0 = aTrMul; - PkOut0 = aPkOut; - } - - /** - * @return "True" if dithering is recursive relative to scanlines meaning - * multi-threaded execution is not supported by this dithering method. - */ - - static bool isRecursive() - { - return( false ); - } - - /** - * Function performs rounding and clipping operations. - * - * @param ResScanline The buffer containing the final scanline. - */ - - void dither( fptype* const ResScanline ) const - { - const fptype c0 = (fptype) 0; - const fptype PkOut = (fptype) PkOut0; - int j; - - if( TrMul0 == 1.0 ) - { - // Optimization - do not perform bit depth truncation. - - for( j = 0; j < LenE; j++ ) - { - ResScanline[ j ] = clamp( round( ResScanline[ j ]), c0, - PkOut ); - } - } - else - { - const fptype TrMul = (fptype) TrMul0; - - for( j = 0; j < LenE; j++ ) - { - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - } - } - } - -protected: - int Len; ///< Scanline's length in pixels. - ///< - const CImageResizerVars* Vars; ///< Image resizing-related variables. - ///< - int LenE; ///< = LenE * ElCount. - ///< - double TrMul0; ///< Bit-depth truncation multiplier. - ///< - double PkOut0; ///< Peak output value allowed. - ///< -}; - -/** - * @brief Image resizer's error-diffusion dithering class, interleaved mode. - * - * This ditherer implements error-diffusion dithering which looks good, and - * whose results are compressed by PNG well. This implementation uses - * weighting coefficients obtained via machine optimization and visual - * evaluation. - * - * @tparam fptype Floating point type to use for storing pixel data. SIMD - * types can be used. - */ - -template< class fptype > -class CImageResizerDithererErrdINL : - public CImageResizerDithererDefINL< fptype > -{ -public: - /** - * Function initializes the ditherer object. - * - * @param aLen Scanline length in pixels to process. - * @param aVars Image resizing-related variables. - * @param aTrMul Bit-depth truncation multiplier. 1 - no additional - * truncation. - * @param aPkOut Peak output value allowed. - */ - - void init( const int aLen, const CImageResizerVars& aVars, - const double aTrMul, const double aPkOut ) - { - CImageResizerDithererDefINL< fptype > :: init( aLen, aVars, aTrMul, - aPkOut ); - - ResScanlineDith0.alloc( LenE + Vars -> ElCount, sizeof( fptype )); - ResScanlineDith = ResScanlineDith0 + Vars -> ElCount; - int i; - - for( i = 0; i < LenE + Vars -> ElCount; i++ ) - { - ResScanlineDith0[ i ] = (fptype) 0; - } - } - - static bool isRecursive() - { - return( true ); - } - - void dither( fptype* const ResScanline ) - { - const int ElCount = Vars -> ElCount; - const fptype c0 = (fptype) 0; - const fptype TrMul = (fptype) TrMul0; - const fptype PkOut = (fptype) PkOut0; - int j; - - for( j = 0; j < LenE; j++ ) - { - ResScanline[ j ] += ResScanlineDith[ j ]; - ResScanlineDith[ j ] = (fptype) 0; - } - - for( j = 0; j < LenE - ElCount; j++ ) - { - // Perform rounding, noise estimation and saturation. - - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - const fptype Noise = ResScanline[ j ] - z0; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - - ResScanline[ j + ElCount ] += Noise * (fptype) 0.364842; - ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; - ResScanlineDith[ j ] += Noise * (fptype) 0.364842; - ResScanlineDith[ j + ElCount ] += Noise * (fptype) 0.063011; - } - - while( j < LenE ) - { - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - const fptype Noise = ResScanline[ j ] - z0; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - - ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; - ResScanlineDith[ j ] += Noise * (fptype) 0.364842; - j++; - } - } - -protected: - using CImageResizerDithererDefINL< fptype > :: Len; - using CImageResizerDithererDefINL< fptype > :: Vars; - using CImageResizerDithererDefINL< fptype > :: LenE; - using CImageResizerDithererDefINL< fptype > :: TrMul0; - using CImageResizerDithererDefINL< fptype > :: PkOut0; - - CBuffer< fptype > ResScanlineDith0; ///< Error diffusion buffer. - ///< - fptype* ResScanlineDith; ///< Error diffusion buffer pointer which skips - ///< the first ElCount elements. - ///< -}; - -/** - * @brief Floating-point processing definition and abstraction class. - * - * This class defines several constants and typedefs that point to classes - * that should be used by the image resizing algorithm. Such "definition - * class" can be used to define alternative scanline processing algorithms - * (e.g. SIMD) and image scanline packing styles used during processing. This - * class also offers an abstraction layer for dithering, rounding and - * clamping (saturation) operation. - * - * The fpclass_def class can be used to define processing using both SIMD and - * non-SIMD types, but using algorithms that operate on interleaved pixels, - * and which are non-SIMD optimized themselves. - * - * @tparam afptype Floating point type to use for storing intermediate data - * and variables. For variables that are not used in intensive calculations - * the "double" type is always used. On the latest Intel processors (like - * i7-4770K) there is almost no performance difference between "double" and - * "float". Image quality differences between "double" and "float" are not - * apparent on 8-bit images. At the same time the "float" uses half amount of - * working memory the "double" type uses. SIMD types can be used. The - * functions round() and clamp() in the "avir" or other visible namespace - * should be available for the specified type. SIMD types allow to perform - * resizing of images with more than 4 channels, to be exact 4 * SIMD element - * number (e.g. 16 for float4), without modification of the image resizing - * algorithm required. - * @tparam afptypeatom The atomic type the "afptype" consists of. - * @tparam adith Ditherer class to use during processing. - */ - -template< class afptype, class afptypeatom = afptype, - class adith = CImageResizerDithererDefINL< afptype > > -class fpclass_def -{ -public: - typedef afptype fptype; ///< Floating-point type to use during processing. - ///< - typedef afptypeatom fptypeatom; ///< Atomic type "fptype" consists of. - ///< - static const int fppack = sizeof( fptype ) / sizeof( fptypeatom ); ///< - ///< The number of atomic types stored in a single "fptype" element. - ///< - static const int fpalign = sizeof( fptype ); ///< Suggested alignment size - ///< in bytes. This is not a required alignment, because image - ///< resizing algorithm cannot be made to have a strictly aligned data - ///< access at all steps (e.g. interpolation cannot perform aligned - ///< accesses). - ///< - static const int elalign = 1; ///< Length alignment of arrays of elements. - ///< This applies to filters and intermediate buffers: this constant - ///< forces filters and scanlines to have a length which is a multiple - ///< of this value, for more efficient SIMD implementation. - ///< - static const int packmode = 0; ///< 0 if interleaved packing, 1 if - ///< de-interleaved. - ///< - typedef CImageResizerFilterStepINL< fptype, fptypeatom > CFilterStep; ///< - ///< Filtering step class to use during processing. - ///< - typedef adith CDitherer; ///< Ditherer class to use during processing. - ///< -}; - -/** - * @brief Image resizer class. - * - * The object of this class can be used to resize 1-4 channel images to any - * required size. Resizing is performed by utilizing interpolated sinc - * fractional delay filters plus (if necessary) a cascade of built-in - * sinc function-based 2X upsampling or 2X downsampling stages, followed by a - * correction filtering. - * - * Object of this class can be allocated on stack. - * - * @tparam fpclass Floating-point processing definition class to use. See - * avir::fpclass_def for more details. - */ - -template< class fpclass = fpclass_def< float > > -class CImageResizer -{ - AVIR_NOCTOR( CImageResizer ); - -public: - /** - * Constructor initializes the resizer. - * - * @param aResBitDepth Required bit depth of resulting image (1-16). If - * integer value output is used (e.g. uint8_t), the bit depth also affects - * rounding: for example, if aResBitDepth=6 and "Tout" is uint8_t, the - * result will be rounded to 6 most significant bits (2 least significant - * bits truncated, with dithering applied). - * @param aSrcBitDepth Source image's real bit-depth. Set to 0 to use - * aResBitDepth. - * @param aParams Resizing algorithm's parameters to use. Leave out for - * default values. Can be useful when performing automatic optimization of - * parameters. - */ - - CImageResizer( const int aResBitDepth = 8, const int aSrcBitDepth = 0, - const CImageResizerParams& aParams = CImageResizerParamsDef() ) - : Params( aParams ) - , ResBitDepth( aResBitDepth ) - { - SrcBitDepth = ( aSrcBitDepth == 0 ? ResBitDepth : aSrcBitDepth ); - - initFilterBank( FixedFilterBank, 1.0, false, CFltBuffer() ); - FixedFilterBank.createAllFilters(); - } - - /** - * Function resizes image. - * - * @param SrcBuf Source image buffer. - * @param SrcWidth Source image width. - * @param SrcHeight Source image height. - * @param SrcScanlineSize Physical size of source scanline in elements - * (not bytes). If this value is below 1, SrcWidth * ElCountIO will be - * used as the physical source scanline size. - * @param[out] NewBuf Buffer to accept the resized image. Can be equal to - * SrcBuf if the size of the resized image is smaller or equal to source - * image in size. - * @param NewWidth New image width. - * @param NewHeight New image height. - * @param ElCountIO The number of elements (channels) used to store each - * source and destination pixel (1-4). - * @param k Resizing step (one output pixel corresponds to "k" input - * pixels). A downsizing factor if > 1.0; upsizing factor if <= 1.0. - * Multiply by -1 if you would like to bypass "ox" and "oy" adjustment - * which is done by default to produce a centered image. If step value - * equals 0, the step value will be chosen automatically and independently - * for horizontal and vertical resizing. - * @param[in,out] aVars Pointer to variables structure to be passed to the - * image resizing function. Can be NULL. Only variables that are - * initialized in default constructor of this structure are accepted by - * this function. These variables will not be changed by this function. - * All other variables can be modified by this function. The access to - * this object is not thread-safe, each concurrent instance of this - * function should use a separate aVars object. - * @tparam Tin Input buffer element's type. Can be uint8_t (0-255 value - * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), - * double (0.0-1.0 value range). Larger integer types are treated as - * uint16_t. Signed integer types are unsupported. - * @tparam Tout Output buffer element's type. Can be uint8_t (0-255 value - * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), - * double (0.0-1.0 value range). Larger integer types are treated as - * uint16_t. Signed integer types are unsupported. - */ - - template< class Tin, class Tout > - void resizeImage( const Tin* const SrcBuf, const int SrcWidth, - const int SrcHeight, int SrcScanlineSize, Tout* const NewBuf, - const int NewWidth, const int NewHeight, const int ElCountIO, - const double k, CImageResizerVars* const aVars = NULL ) const - { - if( SrcWidth == 0 || SrcHeight == 0 ) - { - memset( NewBuf, 0, (size_t) NewWidth * NewHeight * - sizeof( Tout )); - - return; - } - else - if( NewWidth == 0 || NewHeight == 0 ) - { - return; - } - - CImageResizerVars DefVars; - CImageResizerVars& Vars = ( aVars == NULL ? DefVars : *aVars ); - - CImageResizerThreadPool DefThreadPool; - CImageResizerThreadPool& ThreadPool = ( Vars.ThreadPool == NULL ? - DefThreadPool : *Vars.ThreadPool ); - - // Define resizing steps, also optionally modify offsets so that - // resizing produces a "centered" image. - - double kx; - double ky; - double ox = Vars.ox; - double oy = Vars.oy; - - if( k == 0.0 ) - { - kx = (double) SrcWidth / NewWidth; - ox += ( kx - 1.0 ) * 0.5; - - ky = (double) SrcHeight / NewHeight; - oy += ( ky - 1.0 ) * 0.5; - } - else - if( k > 0.0 ) - { - kx = k; - ky = k; - - const double ko = ( k - 1.0 ) * 0.5; - ox += ko; - oy += ko; - } - else - { - kx = -k; - ky = -k; - } - - // Evaluate pre-multipliers used on the output stage. - - const bool IsInFloat = ( (Tin) 0.25 != 0 ); - const bool IsOutFloat = ( (Tout) 0.25 != 0 ); - double OutMul; // Output multiplier. - - if( Vars.UseSRGBGamma ) - { - if( IsInFloat ) - { - Vars.InGammaMult = 1.0; - } - else - { - Vars.InGammaMult = - 1.0 / ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); - } - - if( IsOutFloat ) - { - Vars.OutGammaMult = 1.0; - } - else - { - Vars.OutGammaMult = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); - } - - OutMul = 1.0; - } - else - { - if( IsOutFloat ) - { - OutMul = 1.0; - } - else - { - OutMul = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); - } - - if( !IsInFloat ) - { - OutMul /= ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); - } - } - - // Fill widely-used variables. - - const int ElCount = ( ElCountIO + fpclass :: fppack - 1 ) / - fpclass :: fppack; - - const int NewWidthE = NewWidth * ElCount; - - if( SrcScanlineSize < 1 ) - { - SrcScanlineSize = SrcWidth * ElCountIO; - } - - Vars.ElCount = ElCount; - Vars.ElCountIO = ElCountIO; - Vars.fppack = fpclass :: fppack; - Vars.fpalign = fpclass :: fpalign; - Vars.elalign = fpclass :: elalign; - Vars.packmode = fpclass :: packmode; - - // Horizontal scanline filtering and resizing. - - CDSPFracFilterBankLin< fptype > FltBank; - CFilterSteps FltSteps; - typename CFilterStep :: CRPosBufArray RPosBufArray; - CBuffer< uint8_t > UsedFracMap; - - // Perform the filtering steps modeling at various modes, find the - // most efficient mode for both horizontal and vertical resizing. - - int UseBuildMode = 1; - const int BuildModeCount = - ( FixedFilterBank.getOrder() == 0 ? 4 : 2 ); - - int m; - - if( Vars.BuildMode >= 0 ) - { - UseBuildMode = Vars.BuildMode; - } - else - { - int BestScore = 0x7FFFFFFF; - - for( m = 0; m < BuildModeCount; m++ ) - { - CDSPFracFilterBankLin< fptype > TmpBank; - CFilterSteps TmpSteps; - Vars.k = kx; - Vars.o = ox; - buildFilterSteps( TmpSteps, Vars, TmpBank, OutMul, m, true ); - updateFilterStepBuffers( TmpSteps, Vars, RPosBufArray, - SrcWidth, NewWidth ); - - fillUsedFracMap( TmpSteps[ Vars.ResizeStep ], UsedFracMap ); - const int c = calcComplexity( TmpSteps, Vars, UsedFracMap, - SrcHeight ); - - if( c < BestScore ) - { - UseBuildMode = m; - BestScore = c; - } - } - } - - // Perform the actual filtering steps building. - - Vars.k = kx; - Vars.o = ox; - buildFilterSteps( FltSteps, Vars, FltBank, OutMul, UseBuildMode, - false ); - - updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcWidth, - NewWidth ); - - updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); - - const int ThreadCount = ThreadPool.getSuggestedWorkloadCount(); - // Includes the current thread. - - CStructArray< CThreadData< Tin, Tout > > td; - td.setItemCount( ThreadCount ); - int i; - - for( i = 0; i < ThreadCount; i++ ) - { - if( i > 0 ) - { - ThreadPool.addWorkload( &td[ i ]); - } - - td[ i ].init( i, ThreadCount, FltSteps, Vars ); - - td[ i ].initScanlineQueue( td[ i ].sopResizeH, SrcHeight, - SrcWidth ); - } - - CBuffer< fptype, size_t > FltBuf( (size_t) NewWidthE * SrcHeight, - fpclass :: fpalign ); // Temporary buffer that receives - // horizontally-filtered and resized image. - - for( i = 0; i < SrcHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - (void*) &SrcBuf[ (size_t) i * SrcScanlineSize ], - &FltBuf[ (size_t) i * NewWidthE ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - - // Vertical scanline filtering and resizing, reuse previously defined - // filtering steps if possible. - - const int PrevUseBuildMode = UseBuildMode; - - if( Vars.BuildMode >= 0 ) - { - UseBuildMode = Vars.BuildMode; - } - else - { - CImageResizerVars TmpVars( Vars ); - int BestScore = 0x7FFFFFFF; - - for( m = 0; m < BuildModeCount; m++ ) - { - CDSPFracFilterBankLin< fptype > TmpBank; - TmpBank.copyInitParams( FltBank ); - CFilterSteps TmpSteps; - TmpVars.k = ky; - TmpVars.o = oy; - buildFilterSteps( TmpSteps, TmpVars, TmpBank, 1.0, m, true ); - updateFilterStepBuffers( TmpSteps, TmpVars, RPosBufArray, - SrcHeight, NewHeight ); - - fillUsedFracMap( TmpSteps[ TmpVars.ResizeStep ], - UsedFracMap ); - - const int c = calcComplexity( TmpSteps, TmpVars, UsedFracMap, - NewWidth ); - - if( c < BestScore ) - { - UseBuildMode = m; - BestScore = c; - } - } - } - - Vars.k = ky; - Vars.o = oy; - - if( UseBuildMode == PrevUseBuildMode && ky == kx ) - { - if( OutMul != 1.0 ) - { - modifyCorrFilterDCGain( FltSteps, 1.0 / OutMul ); - } - } - else - { - buildFilterSteps( FltSteps, Vars, FltBank, 1.0, UseBuildMode, - false ); - } - - updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcHeight, - NewHeight ); - - updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); - - if( IsOutFloat && sizeof( FltBuf[ 0 ]) == sizeof( Tout ) && - fpclass :: packmode == 0 ) - { - // In-place output. - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, - SrcHeight, NewWidthE, NewWidthE ); - } - - for( i = 0; i < NewWidth; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &FltBuf[ (size_t) i * ElCount ], - (fptype*) &NewBuf[ (size_t) i * ElCount ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - ThreadPool.removeAllWorkloads(); - - return; - } - - CBuffer< fptype, size_t > ResBuf( (size_t) NewWidthE * NewHeight, - fpclass :: fpalign ); - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, - SrcHeight, NewWidthE, NewWidthE ); - } - - const int im = ( fpclass :: packmode == 0 ? ElCount : 1 ); - - for( i = 0; i < NewWidth; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &FltBuf[ (size_t) i * im ], &ResBuf[ (size_t) i * im ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - - if( IsOutFloat ) - { - // Perform output, but skip dithering. - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopUnpackH, - NewHeight, NewWidth ); - } - - for( i = 0; i < NewHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &ResBuf[ (size_t) i * NewWidthE ], - &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - ThreadPool.removeAllWorkloads(); - - return; - } - - // Perform output with dithering (for integer output only). - - int TruncBits; // The number of lower bits to truncate and dither. - int OutRange; // Output range. - - if( sizeof( Tout ) == 1 ) - { - TruncBits = 8 - ResBitDepth; - OutRange = 255; - } - else - { - TruncBits = 16 - ResBitDepth; - OutRange = 65535; - } - - const double PkOut = OutRange; - const double TrMul = ( TruncBits > 0 ? - PkOut / ( OutRange >> TruncBits ) : 1.0 ); - - if( CDitherer :: isRecursive() ) - { - td[ 0 ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); - - if( Vars.UseSRGBGamma ) - { - for( i = 0; i < NewHeight; i++ ) - { - fptype* const ResScanline = - &ResBuf[ (size_t) i * NewWidthE ]; - - CFilterStep :: applySRGBGamma( ResScanline, NewWidth, - Vars ); - - td[ 0 ].getDitherer().dither( ResScanline ); - - CFilterStep :: unpackScanline( ResScanline, - &NewBuf[ (size_t) i * NewWidth * ElCountIO ], - NewWidth, Vars ); - } - } - else - { - for( i = 0; i < NewHeight; i++ ) - { - fptype* const ResScanline = - &ResBuf[ (size_t) i * NewWidthE ]; - - td[ 0 ].getDitherer().dither( ResScanline ); - - CFilterStep :: unpackScanline( ResScanline, - &NewBuf[ (size_t) i * NewWidth * ElCountIO ], - NewWidth, Vars ); - } - } - } - else - { - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopDitherAndUnpackH, - NewHeight, NewWidth ); - - td[ i ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); - } - - for( i = 0; i < NewHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &ResBuf[ (size_t) i * NewWidthE ], - &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - } - - ThreadPool.removeAllWorkloads(); - } - -private: - typedef typename fpclass :: fptype fptype; ///< Floating-point type to use - ///< during processing. - ///< - typedef typename fpclass :: CFilterStep CFilterStep; ///< Filtering step - ///< class to use during processing. - ///< - typedef typename fpclass :: CDitherer CDitherer; ///< Ditherer class to - ///< use during processing. - ///< - CImageResizerParams Params; ///< Algorithm's parameters currently in use. - ///< - int SrcBitDepth; ///< Bit resolution of the source image. - ///< - int ResBitDepth; ///< Bit resolution of the resulting image. - ///< - CDSPFracFilterBankLin< fptype > FixedFilterBank; ///< Fractional delay - ///< filter bank with fixed characteristics, mainly for upsizing - ///< cases. - ///< - - /** - * @brief Filtering steps array. - * - * The object of this class stores filtering steps together. - */ - - typedef CStructArray< CFilterStep > CFilterSteps; - - /** - * Function initializes the filter bank in the specified resizing step - * according to the source and resulting image bit depths. - * - * @param FltBank Filter bank to initialize. - * @param CutoffMult Cutoff multiplier, 0 to 1. 1 corresponds to 0.5pi - * cutoff point. - * @param ForceHiOrder "True" if a high-order interpolation should be - * forced which requires considerably less resources for initialization. - * @param ExtFilter External filter to apply to interpolation filter. - */ - - void initFilterBank( CDSPFracFilterBankLin< fptype >& FltBank, - const double CutoffMult, const bool ForceHiOrder, - const CFltBuffer& ExtFilter ) const - { - const int IntBitDepth = ( ResBitDepth > SrcBitDepth ? ResBitDepth : - SrcBitDepth ); - - const double SNR = -6.02 * ( IntBitDepth + 3 ); - int UseOrder; - int FracCount; // The number of fractional delay filters sampled by - // the filter bank. This variable affects the signal-to-noise - // ratio at interpolation stage. Theoretically, at UseOrder==1, - // 8-bit image resizing requires 66.2 dB SNR or 11. 16-bit - // resizing requires 114.4 dB SNR or 150. At UseOrder=0 the - // required number of filters is exponentially higher. - - if( ForceHiOrder || IntBitDepth > 8 ) - { - UseOrder = 1; // -146 dB max - FracCount = (int) ceil( 0.23134052 * exp( -0.058062929 * SNR )); - } - else - { - UseOrder = 0; // -72 dB max - FracCount = (int) ceil( 0.33287686 * exp( -0.11334583 * SNR )); - } - - if( FracCount < 2 ) - { - FracCount = 2; - } - - FltBank.init( FracCount, UseOrder, Params.IntFltLen / CutoffMult, - Params.IntFltCutoff * CutoffMult, Params.IntFltAlpha, ExtFilter, - fpclass :: fpalign, fpclass :: elalign ); - } - - /** - * Function allocates filter buffer taking "fpclass" alignments into - * account. The allocated buffer may be larger than the requested size: in - * this case the additional elements will be zeroed by this function. - * - * @param Flt Filter buffer. - * @param ReqCapacity The required filter buffer's capacity. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter allocation. - * @param FltExt If non-NULL this variable will receive the number of - * elements the filter was extended by. - */ - - static void allocFilter( CBuffer< fptype >& Flt, const int ReqCapacity, - const bool IsModel = false, int* const FltExt = NULL ) - { - int UseCapacity = ( ReqCapacity + fpclass :: elalign - 1 ) & - ~( fpclass :: elalign - 1 ); - - int Ext = UseCapacity - ReqCapacity; - - if( FltExt != NULL ) - { - *FltExt = Ext; - } - - if( IsModel ) - { - Flt.forceCapacity( UseCapacity ); - return; - } - - Flt.alloc( UseCapacity, fpclass :: fpalign ); - - while( Ext > 0 ) - { - Ext--; - Flt[ ReqCapacity + Ext ] = (fptype) 0; - } - } - - /** - * Function assigns filter parameters to the specified filtering step - * object. - * - * @param fs Filtering step to assign parameter to. This step cannot be - * the last step if ResampleFactor greater than 1 was specified. - * @param IsUpsample "True" if upsampling step. Should be set to "false" - * if FltCutoff is negative. - * @param ResampleFactor Resampling factor of this filter (>=1). - * @param FltCutoff Filter cutoff point. This value will be divided by the - * ResampleFactor if IsUpsample equals "true". If zero value was - * specified, the "half-band" predefined filter will be created. In this - * case the ResampleFactor will modify the filter cutoff point. - * @param DCGain DC gain to apply to the filter. Assigned to filtering - * step's DCGain variable. - * @param UseFltOrig "True" if the originally-designed filter should be - * left in filtering step's FltOrig buffer. Otherwise it will be freed. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - void assignFilterParams( CFilterStep& fs, const bool IsUpsample, - const int ResampleFactor, const double FltCutoff, const double DCGain, - const bool UseFltOrig, const bool IsModel ) const - { - double FltAlpha; - double Len2; - double Freq; - - if( FltCutoff == 0.0 ) - { - const double m = 2.0 / ResampleFactor; - FltAlpha = Params.HBFltAlpha; - Len2 = 0.5 * Params.HBFltLen / m; - Freq = AVIR_PI * Params.HBFltCutoff * m; - } - else - { - FltAlpha = Params.LPFltAlpha; - Len2 = 0.25 * Params.LPFltBaseLen / FltCutoff; - Freq = AVIR_PI * Params.LPFltCutoffMult * FltCutoff; - } - - if( IsUpsample ) - { - Len2 *= ResampleFactor; - Freq /= ResampleFactor; - fs.DCGain = DCGain * ResampleFactor; - } - else - { - fs.DCGain = DCGain; - } - - fs.FltOrig.Len2 = Len2; - fs.FltOrig.Freq = Freq; - fs.FltOrig.Alpha = FltAlpha; - fs.FltOrig.DCGain = fs.DCGain; - - CDSPPeakedCosineLPF w( Len2, Freq, FltAlpha ); - - fs.IsUpsample = IsUpsample; - fs.ResampleFactor = ResampleFactor; - fs.FltLatency = w.fl2; - - int FltExt; // Filter's extension due to fpclass :: elalign. - - if( IsModel ) - { - allocFilter( fs.Flt, w.FilterLen, true, &FltExt ); - - if( UseFltOrig ) - { - // Allocate a real buffer even in modeling mode since this - // filter may be copied by the filter bank. - - fs.FltOrig.alloc( w.FilterLen ); - memset( &fs.FltOrig[ 0 ], 0, - w.FilterLen * sizeof( fs.FltOrig[ 0 ])); - } - } - else - { - fs.FltOrig.alloc( w.FilterLen ); - - w.generateLPF( &fs.FltOrig[ 0 ], fs.DCGain ); - - allocFilter( fs.Flt, fs.FltOrig.getCapacity(), false, &FltExt ); - copyArray( &fs.FltOrig[ 0 ], &fs.Flt[ 0 ], - fs.FltOrig.getCapacity() ); - - if( !UseFltOrig ) - { - fs.FltOrig.free(); - } - } - - if( IsUpsample ) - { - int l = fs.Flt.getCapacity() - fs.FltLatency - ResampleFactor - - FltExt; - - allocFilter( fs.PrefixDC, l, IsModel ); - allocFilter( fs.SuffixDC, fs.FltLatency, IsModel ); - - if( IsModel ) - { - return; - } - - // Create prefix and suffix "tails" used during upsampling. - - const fptype* ip = &fs.Flt[ fs.FltLatency + ResampleFactor ]; - copyArray( ip, &fs.PrefixDC[ 0 ], l ); - - while( true ) - { - ip += ResampleFactor; - l -= ResampleFactor; - - if( l <= 0 ) - { - break; - } - - addArray( ip, &fs.PrefixDC[ 0 ], l ); - } - - l = fs.FltLatency; - fptype* op = &fs.SuffixDC[ 0 ]; - copyArray( &fs.Flt[ 0 ], op, l ); - - while( true ) - { - op += ResampleFactor; - l -= ResampleFactor; - - if( l <= 0 ) - { - break; - } - - addArray( &fs.Flt[ 0 ], op, l ); - } - } - else - if( !UseFltOrig ) - { - fs.EdgePixelCount = fs.EdgePixelCountDef; - } - } - - /** - * Function adds a correction filter that tries to achieve a linear - * frequency response at all frequencies. The actual resulting response - * may feature a slight damping of the highest frequencies since a - * suitably short correction filter cannot fix steep high-frequency - * damping. - * - * This function assumes that the resizing step is currently the last - * step, even if it was not inserted yet: this allows placement of the - * correction filter both before and after the resizing step. - * - * @param Steps Filtering steps. - * @param bw Resulting bandwidth relative to the original bandwidth (which - * is 1.0), usually 1/k. Should be <= 1.0. - * @param IsPreCorrection "True" if the filtering step was already created - * and it is first in the Steps array. "True" also adds edge pixels to - * reduce edge artifacts. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - void addCorrectionFilter( CFilterSteps& Steps, const double bw, - const bool IsPreCorrection, const bool IsModel ) const - { - CFilterStep& fs = ( IsPreCorrection ? Steps[ 0 ] : Steps.add() ); - fs.IsUpsample = false; - fs.ResampleFactor = 1; - fs.DCGain = 1.0; - fs.EdgePixelCount = ( IsPreCorrection ? fs.EdgePixelCountDef : 0 ); - - if( IsModel ) - { - allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( - Params.CorrFltLen, fs.FltLatency ), true ); - - return; - } - - const int BinCount = 65; // Frequency response bins to control. - const int BinCount1 = BinCount - 1; - double curbw = 1.0; // Bandwidth of the filter at the current step. - int i; - int j; - double re; - double im; - - CBuffer< double > Bins( BinCount ); // Adjustment introduced by all - // steps at all frequencies of interest. - - for( j = 0; j < BinCount; j++ ) - { - Bins[ j ] = 1.0; - } - - const int si = ( IsPreCorrection ? 1 : 0 ); - - for( i = si; i < Steps.getItemCount() - ( si ^ 1 ); i++ ) - { - const CFilterStep& fs = Steps[ i ]; - - if( fs.IsUpsample ) - { - curbw *= fs.ResampleFactor; - - if( fs.FltOrig.getCapacity() > 0 ) - { - continue; - } - } - - const fptype* Flt; - int FltLen; - - if( fs.ResampleFactor == 0 ) - { - Flt = fs.FltBank -> getFilter( 0 ); - FltLen = fs.FltBank -> getFilterLen(); - } - else - { - Flt = &fs.Flt[ 0 ]; - FltLen = fs.Flt.getCapacity(); - } - - // Calculate frequency response adjustment introduced by the - // filter at this step, within the bounds of bandwidth of - // interest. - - const double thm = AVIR_PI * bw / ( curbw * BinCount1 ); - - for( j = 0; j < BinCount; j++ ) - { - calcFIRFilterResponse( Flt, FltLen, j * thm, re, im ); - - Bins[ j ] *= fs.DCGain / sqrt( re * re + im * im ); - } - - if( !fs.IsUpsample && fs.ResampleFactor > 1 ) - { - curbw /= fs.ResampleFactor; - } - } - - // Calculate filter. - - CDSPFIREQ EQ; - EQ.init( bw * 2.0, Params.CorrFltLen, BinCount, 0.0, bw, false, - Params.CorrFltAlpha ); - - fs.FltLatency = EQ.getFilterLatency(); - - CBuffer< double > Filter( EQ.getFilterLength() ); - EQ.buildFilter( Bins, &Filter[ 0 ]); - normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); - - allocFilter( fs.Flt, Filter.getCapacity() ); - copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); - - // Print a theoretically achieved final frequency response at various - // feature sizes (from DC to 1 pixel). Values above 255 means features - // become brighter, values below 255 means features become dimmer. - -/* const double sbw = ( bw > 1.0 ? 1.0 / bw : 1.0 ); - - for( j = 0; j < BinCount; j++ ) - { - const double th = AVIR_PI * sbw * j / BinCount1; - - calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), - th, re, im ); - - printf( "%f\n", sqrt( re * re + im * im ) / Bins[ j ] * 255 ); - } - - printf( "***\n" );*/ - } - - /** - * Function adds a sharpening filter if image is being upsized. Such - * sharpening allows to spot interpolation filter's stop-band attenuation: - * if attenuation is too weak, a "dark grid" and other artifacts may - * become visible. - * - * It is assumed that 40 decibel stop-band attenuation should be - * considered a required minimum: this allows application of (deliberately - * strong) 64X sharpening without spotting any artifacts. - * - * @param Steps Filtering steps. - * @param bw Resulting bandwidth relative to the original bandwidth (which - * is 1.0), usually 1/k. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - static void addSharpenTest( CFilterSteps& Steps, const double bw, - const bool IsModel ) - { - if( bw <= 1.0 ) - { - return; - } - - const double FltLen = 10.0 * bw; - - CFilterStep& fs = Steps.add(); - fs.IsUpsample = false; - fs.ResampleFactor = 1; - fs.DCGain = 1.0; - fs.EdgePixelCount = 0; - - if( IsModel ) - { - allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( FltLen, - fs.FltLatency ), true ); - - return; - } - - const int BinCount = 200; - CBuffer< double > Bins( BinCount ); - int Thresh = (int) round( BinCount / bw * 1.75 ); - - if( Thresh > BinCount ) - { - Thresh = BinCount; - } - - int j; - - for( j = 0; j < Thresh; j++ ) - { - Bins[ j ] = 1.0; - } - - for( j = Thresh; j < BinCount; j++ ) - { - Bins[ j ] = 256.0; - } - - CDSPFIREQ EQ; - EQ.init( bw * 2.0, FltLen, BinCount, 0.0, bw, false, 1.7 ); - - fs.FltLatency = EQ.getFilterLatency(); - - CBuffer< double > Filter( EQ.getFilterLength() ); - EQ.buildFilter( Bins, &Filter[ 0 ]); - normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); - - allocFilter( fs.Flt, Filter.getCapacity() ); - copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); - -/* for( j = 0; j < BinCount; j++ ) - { - const double th = AVIR_PI * j / ( BinCount - 1 ); - double re; - double im; - - calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), - th, re, im ); - - printf( "%f\n", sqrt( re * re + im * im )); - } - - printf( "***\n" );*/ - } - - /** - * Function builds sequence of filtering steps depending on the specified - * resizing coefficient. The last steps included are always the resizing - * step then (possibly) the correction step. - * - * @param Steps Array that receives filtering steps. - * @param[out] Vars Variables object. - * @param FltBank Filter bank to initialize and use. - * @param DCGain The overall DC gain to apply. This DC gain is applied to - * the first filtering step only (upsampling or filtering step). - * @param ModeFlags Build mode flags to use. This is a bitmap of switches - * that enable or disable certain algorithm features. - * @param IsModel "True" if filtering steps modeling is performed without - * the actual filter allocation and building. - */ - - void buildFilterSteps( CFilterSteps& Steps, CImageResizerVars& Vars, - CDSPFracFilterBankLin< fptype >& FltBank, const double DCGain, - const int ModeFlags, const bool IsModel ) const - { - Steps.clear(); - - const bool DoFltAndIntCombo = (( ModeFlags & 1 ) != 0 ); // Do filter - // and interpolator combining. - const bool ForceHiOrderInt = (( ModeFlags & 2 ) != 0 ); // Force use - // of a higher-order interpolation. - const bool UseHalfband = (( ModeFlags & 4 ) != 0 ); // Use half-band - // filter. - - const double bw = 1.0 / Vars.k; // Resulting bandwidth. - const int UpsampleFactor = ( (int) floor( Vars.k ) < 2 ? 2 : 1 ); - double IntCutoffMult; // Interpolation filter cutoff multiplier. - CFilterStep* ReuseStep; // If not NULL, resizing step should use - // this step object instead of creating a new one. - CFilterStep* ExtFltStep; // Use FltOrig of this step as the external - // filter to applied to the interpolator. - bool IsPreCorrection; // "True" if the correction filter is applied - // first. - double FltCutoff; // Cutoff frequency of the first filtering step. - double corrbw; ///< Bandwidth at the correction step. - - if( Vars.k <= 1.0 ) - { - IsPreCorrection = true; - FltCutoff = 1.0; - corrbw = 1.0; - Steps.add(); - } - else - { - IsPreCorrection = false; - FltCutoff = bw; - corrbw = bw; - } - - // Add 1 upsampling or several downsampling filters. - - if( UpsampleFactor > 1 ) - { - CFilterStep& fs = Steps.add(); - assignFilterParams( fs, true, UpsampleFactor, FltCutoff, DCGain, - DoFltAndIntCombo, IsModel ); - - IntCutoffMult = FltCutoff * 2.0 / UpsampleFactor; - ReuseStep = NULL; - ExtFltStep = ( DoFltAndIntCombo ? &fs : NULL ); - } - else - { - int DownsampleFactor; - - while( true ) - { - DownsampleFactor = (int) floor( 0.5 / FltCutoff ); - bool DoHBFltAdd = ( UseHalfband && DownsampleFactor > 1 ); - - if( DoHBFltAdd ) - { - assignFilterParams( Steps.add(), false, DownsampleFactor, - 0.0, 1.0, false, IsModel ); - - FltCutoff *= DownsampleFactor; - } - else - { - if( DownsampleFactor < 1 ) - { - DownsampleFactor = 1; - } - - break; - } - } - - CFilterStep& fs = Steps.add(); - assignFilterParams( fs, false, DownsampleFactor, FltCutoff, - DCGain, DoFltAndIntCombo, IsModel ); - - IntCutoffMult = FltCutoff / 0.5; - - if( DoFltAndIntCombo ) - { - ReuseStep = &fs; - ExtFltStep = &fs; - } - else - { - IntCutoffMult *= DownsampleFactor; - ReuseStep = NULL; - ExtFltStep = NULL; - } - } - - // Insert resizing and correction steps. - - CFilterStep& fs = ( ReuseStep == NULL ? Steps.add() : *ReuseStep ); - - Vars.ResizeStep = Steps.getItemCount() - 1; - fs.IsUpsample = false; - fs.ResampleFactor = 0; - fs.DCGain = ( ExtFltStep == NULL ? 1.0 : ExtFltStep -> DCGain ); - - initFilterBank( FltBank, IntCutoffMult, ForceHiOrderInt, - ( ExtFltStep == NULL ? fs.FltOrig : ExtFltStep -> FltOrig )); - - if( FltBank == FixedFilterBank ) - { - fs.FltBank = (CDSPFracFilterBankLin< fptype >*) &FixedFilterBank; - } - else - { - fs.FltBank = &FltBank; - } - - addCorrectionFilter( Steps, corrbw, IsPreCorrection, IsModel ); - - //addSharpenTest( Steps, bw, IsModel ); - } - - /** - * Function extends *this upsampling step so that it produces more - * upsampled pixels that cover the prefix and suffix needs of the next - * step. After the call to this function the InPrefix and InSuffix - * variables of the next step will be set to zero. - * - * @param fs Upsampling filtering step. - * @param NextStep The next step structure. - */ - - static void extendUpsample( CFilterStep& fs, CFilterStep& NextStep ) - { - fs.InPrefix = ( NextStep.InPrefix + fs.ResampleFactor - 1 ) / - fs.ResampleFactor; - - fs.OutPrefix += fs.InPrefix * fs.ResampleFactor; - NextStep.InPrefix = 0; - - fs.InSuffix = ( NextStep.InSuffix + fs.ResampleFactor - 1 ) / - fs.ResampleFactor; - - fs.OutSuffix += fs.InSuffix * fs.ResampleFactor; - NextStep.InSuffix = 0; - } - - /** - * Function fills resizing step's RPosBuf array, excluding the actual - * "ftp" pointers and "SrcOffs" offsets. - * - * This array should be cleared if the resizing step or offset were - * changed. Otherwise this function only fills the elements required to - * cover resizing step's OutLen. - * - * This function is called by the updateFilterStepBuffers() function. - * - * @param fs Resizing step. - * @param Vars Variables object. - */ - - static void fillRPosBuf( CFilterStep& fs, const CImageResizerVars& Vars ) - { - const int PrevLen = fs.RPosBuf -> getCapacity(); - - if( fs.OutLen > PrevLen ) - { - fs.RPosBuf -> increaseCapacity( fs.OutLen ); - } - - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ PrevLen ]; - const int FracCount = fs.FltBank -> getFracCount(); - const double o = Vars.o; - const double k = Vars.k; - int i; - - for( i = PrevLen; i < fs.OutLen; i++ ) - { - const double SrcPos = o + k * i; - const int SrcPosInt = (int) floor( SrcPos ); - const double x = ( SrcPos - SrcPosInt ) * FracCount; - const int fti = (int) x; - rpos -> x = (typename fpclass :: fptypeatom) ( x - fti ); - rpos -> fti = fti; - rpos -> SrcPosInt = SrcPosInt; - rpos++; - } - } - - /** - * Function updates filtering step buffer lengths depending on the - * specified source and new scanline lengths. This function should be - * called after the buildFilterSteps() function. - * - * @param Steps Array that receives filtering steps. - * @param[out] Vars Variables object, will receive buffer size and length. - * This function expects "k" and "o" variable values that will be - * adjusted by this function. - * @param RPosBufArray Resizing position buffers array, used to obtain - * buffer to initialize and use (will be reused if it is already fully or - * partially filled). - * @param SrcLen Source scanline's length in pixels. - * @param NewLen New scanline's length in pixels. - */ - - static void updateFilterStepBuffers( CFilterSteps& Steps, - CImageResizerVars& Vars, - typename CFilterStep :: CRPosBufArray& RPosBufArray, int SrcLen, - const int NewLen ) - { - int upstep = -1; - int InBuf = 0; - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - - fs.Vars = &Vars; - fs.InLen = SrcLen; - fs.InBuf = InBuf; - fs.OutBuf = ( InBuf + 1 ) & 1; - - if( fs.IsUpsample ) - { - upstep = i; - Vars.k *= fs.ResampleFactor; - Vars.o *= fs.ResampleFactor; - fs.InPrefix = 0; - fs.InSuffix = 0; - fs.OutLen = fs.InLen * fs.ResampleFactor; - fs.OutPrefix = fs.FltLatency; - fs.OutSuffix = fs.Flt.getCapacity() - fs.FltLatency - - fs.ResampleFactor; - - int l0 = fs.OutPrefix + fs.OutLen + fs.OutSuffix; - int l = fs.InLen * fs.ResampleFactor + - fs.SuffixDC.getCapacity(); - - if( l > l0 ) - { - fs.OutSuffix += l - l0; - } - - l0 = fs.OutLen + fs.OutSuffix; - - if( fs.PrefixDC.getCapacity() > l0 ) - { - fs.OutSuffix += fs.PrefixDC.getCapacity() - l0; - } - } - else - if( fs.ResampleFactor == 0 ) - { - const int FilterLenD2 = fs.FltBank -> getFilterLen() / 2; - const int FilterLenD21 = FilterLenD2 - 1; - - const int ResizeLPix = (int) floor( Vars.o ) - FilterLenD21; - fs.InPrefix = ( ResizeLPix < 0 ? -ResizeLPix : 0 ); - const int ResizeRPix = (int) floor( Vars.o + - ( NewLen - 1 ) * Vars.k ) + FilterLenD2 + 1; - - fs.InSuffix = ( ResizeRPix > fs.InLen ? - ResizeRPix - fs.InLen : 0 ); - - fs.OutLen = NewLen; - fs.RPosBuf = &RPosBufArray.getRPosBuf( Vars.k, Vars.o, - fs.FltBank -> getFracCount() ); - - fillRPosBuf( fs, Vars ); - } - else - { - Vars.k /= fs.ResampleFactor; - Vars.o /= fs.ResampleFactor; - Vars.o += fs.EdgePixelCount; - - fs.InPrefix = fs.FltLatency; - fs.InSuffix = fs.Flt.getCapacity() - fs.FltLatency - 1; - - // Additionally extend OutLen to produce more precise edge - // pixels. - - fs.OutLen = ( fs.InLen + fs.ResampleFactor - 1 ) / - fs.ResampleFactor + fs.EdgePixelCount; - - fs.InSuffix += ( fs.OutLen - 1 ) * fs.ResampleFactor + 1 - - fs.InLen; - - fs.InPrefix += fs.EdgePixelCount * fs.ResampleFactor; - fs.OutLen += fs.EdgePixelCount; - } - - InBuf = fs.OutBuf; - SrcLen = fs.OutLen; - } - - Steps[ Steps.getItemCount() - 1 ].OutBuf = 2; - Vars.IsResize2 = false; - - if( upstep != -1 ) - { - extendUpsample( Steps[ upstep ], Steps[ upstep + 1 ]); - - if( Steps[ upstep ].ResampleFactor == 2 && - Vars.ResizeStep == upstep + 1 && - fpclass :: packmode == 0 && - Steps[ upstep ].FltOrig.getCapacity() > 0 ) - { - // Interpolation with preceeding 2x filterless upsample, - // interleaved resizing only. - - Vars.IsResize2 = true; - } - } - } - - /** - * Function calculates an optimal intermediate buffer length that will - * cover all needs of the specified filtering steps. This function should - * be called after the updateFilterStepBuffers() function. - * - * Function also updates resizing step's RPosBuf pointers to the filter - * bank and SrcOffs values. - * - * @param Steps Filtering steps. - * @param[out] Vars Variables object, will receive buffer size and length. - * @param ResElIncr Resulting (final) element increment, used to produce - * de-interleaved result. For horizontal processing this value is equal - * to last step's OutLen, for vertical processing this value is equal to - * resulting image's width. - */ - - static void updateBufLenAndRPosPtrs( CFilterSteps& Steps, - CImageResizerVars& Vars, const int ResElIncr ) - { - int MaxPrefix[ 2 ] = { 0, 0 }; - int MaxLen[ 2 ] = { 0, 0 }; - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - const int ib = fs.InBuf; - - if( fs.InPrefix > MaxPrefix[ ib ]) - { - MaxPrefix[ ib ] = fs.InPrefix; - } - - int l = fs.InLen + fs.InSuffix; - - if( l > MaxLen[ ib ]) - { - MaxLen[ ib ] = l; - } - - fs.InElIncr = fs.InPrefix + l; - - if( fs.OutBuf == 2 ) - { - break; - } - - const int ob = fs.OutBuf; - - if( fs.IsUpsample ) - { - if( fs.OutPrefix > MaxPrefix[ ob ]) - { - MaxPrefix[ ob ] = fs.OutPrefix; - } - - l = fs.OutLen + fs.OutSuffix; - - if( l > MaxLen[ ob ]) - { - MaxLen[ ob ] = l; - } - } - else - { - if( fs.OutLen > MaxLen[ ob ]) - { - MaxLen[ ob ] = fs.OutLen; - } - } - } - - // Update OutElIncr values of all steps. - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - - if( fs.OutBuf == 2 ) - { - fs.OutElIncr = ResElIncr; - break; - } - - CFilterStep& fs2 = Steps[ i + 1 ]; - - if( fs.IsUpsample ) - { - fs.OutElIncr = fs.OutPrefix + fs.OutLen + fs.OutSuffix; - - if( fs.OutElIncr > fs2.InElIncr ) - { - fs2.InElIncr = fs.OutElIncr; - } - else - { - fs.OutElIncr = fs2.InElIncr; - } - } - else - { - fs.OutElIncr = fs2.InElIncr; - } - } - - // Update temporary buffer's length. - - for( i = 0; i < 2; i++ ) - { - Vars.BufLen[ i ] = MaxPrefix[ i ] + MaxLen[ i ]; - Vars.BufOffs[ i ] = MaxPrefix[ i ]; - - if( Vars.packmode == 0 ) - { - Vars.BufOffs[ i ] *= Vars.ElCount; - } - - Vars.BufLen[ i ] *= Vars.ElCount; - } - - // Update RPosBuf pointers and SrcOffs. - - CFilterStep& fs = Steps[ Vars.ResizeStep ]; - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; - const int em = ( fpclass :: packmode == 0 ? Vars.ElCount : 1 ); - const int fl = fs.FltBank -> getFilterLen(); - const int FilterLenD21 = fl / 2 - 1; - - if( Vars.IsResize2 ) - { - for( i = 0; i < fs.OutLen; i++ ) - { - const int p = rpos -> SrcPosInt - FilterLenD21; - const int fo = p & 1; - rpos -> SrcOffs = ( p + fo ) * em; - rpos -> ftp = fs.FltBank -> getFilter( rpos -> fti ) + fo; - rpos -> fl = fl - fo; - rpos++; - } - } - else - { - for( i = 0; i < fs.OutLen; i++ ) - { - rpos -> SrcOffs = ( rpos -> SrcPosInt - FilterLenD21 ) * em; - rpos -> ftp = fs.FltBank -> getFilter( rpos -> fti ); - rpos++; - } - } - } - - /** - * Function modifies the overall (DC) gain of the correction filter in the - * pre-built filtering steps array. - * - * @param Steps Filtering steps. - * @param m Multiplier to apply to the correction filter. - */ - - void modifyCorrFilterDCGain( CFilterSteps& Steps, const double m ) const - { - CBuffer< fptype >* Flt; - const int z = Steps.getItemCount() - 1; - - if( !Steps[ z ].IsUpsample && Steps[ z ].ResampleFactor == 1 ) - { - Flt = &Steps[ z ].Flt; - } - else - { - Flt = &Steps[ 0 ].Flt; - } - - int i; - - for( i = 0; i < Flt -> getCapacity(); i++ ) - { - (*Flt)[ i ] = (fptype) ( (double) (*Flt)[ i ] * m ); - } - } - - /** - * Function builds a map of used fractional delay filters based on the - * resizing positions buffer. - * - * @param fs Resizing step. - * @param[out] UsedFracMap Map of used fractional delay filters. - */ - - static void fillUsedFracMap( const CFilterStep& fs, - CBuffer< uint8_t >& UsedFracMap ) - { - const int FracCount = fs.FltBank -> getFracCount(); - UsedFracMap.increaseCapacity( FracCount, false ); - memset( &UsedFracMap[ 0 ], 0, FracCount * sizeof( UsedFracMap[ 0 ])); - - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; - int i; - - for( i = 0; i < fs.OutLen; i++ ) - { - UsedFracMap[ rpos -> fti ] |= 1; - rpos++; - } - } - - /** - * Function calculates the overall filtering steps complexity per - * scanline. Each complexity unit corresponds to a single multiply-add - * operation. Data copy and pointer math operations are not included in - * this calculation, it is assumed that they correlate to the multiply-add - * operations. Calculation also does not include final rounding, dithering - * and clamping operations since they cannot be optimized out anyway. - * - * Calculation of the CRPosBuf buffer is not included since it cannot be - * avoided. - * - * This function should be called after the updateFilterStepBuffers() - * function. - * - * @param Steps Filtering steps array. - * @param Vars Variables object. - * @param UsedFracMap The map of used fractional delay filters. - * @param ScanlineCount Scanline count. - */ - - static int calcComplexity( const CFilterSteps& Steps, - const CImageResizerVars& Vars, const CBuffer< uint8_t >& UsedFracMap, - const int ScanlineCount ) - { - int fcnum; // Filter complexity multiplier numerator. - int fcdenom; // Filter complexity multiplier denominator. - - if( Vars.packmode != 0 ) - { - fcnum = 1; - fcdenom = 1; - } - else - { - // In interleaved processing mode, filters require 1 less - // multiplication per 2 multiply-add instructions. - - fcnum = 3; - fcdenom = 4; - } - - int s = 0; // Complexity per one scanline. - int s2 = 0; // Complexity per all scanlines. - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - const CFilterStep& fs = Steps[ i ]; - - s2 += 65 * fs.Flt.getCapacity(); // Filter creation complexity. - - if( fs.IsUpsample ) - { - if( fs.FltOrig.getCapacity() > 0 ) - { - continue; - } - - s += ( fs.Flt.getCapacity() * - ( fs.InPrefix + fs.InLen + fs.InSuffix ) + - fs.SuffixDC.getCapacity() + fs.PrefixDC.getCapacity() ) * - Vars.ElCount; - } - else - if( fs.ResampleFactor == 0 ) - { - s += fs.FltBank -> getFilterLen() * - ( fs.FltBank -> getOrder() + Vars.ElCount ) * fs.OutLen; - - if( i == Vars.ResizeStep && Vars.IsResize2 ) - { - s >>= 1; - } - - s2 += fs.FltBank -> calcInitComplexity( UsedFracMap ); - } - else - { - s += fs.Flt.getCapacity() * Vars.ElCount * fs.OutLen * - fcnum / fcdenom; - } - } - - return( s + s2 / ScanlineCount ); - } - - /** - * @brief Thread-isolated data used for scanline processing. - * - * This structure holds data necessary for image's horizontal or vertical - * scanline processing, including scanline processing queue. - * - * @tparam Tin Source element data type. Intermediate buffers store data - * in floating point format. - * @tparam Tout Destination element data type. Intermediate buffers store - * data in floating point format. - */ - - template< class Tin, class Tout > - class CThreadData : public CImageResizerThreadPool :: CWorkload - { - public: - virtual void process() - { - processScanlineQueue(); - } - - /** - * This enumeration lists possible scanline operations. - */ - - enum EScanlineOperation - { - sopResizeH, ///< Resize horizontal scanline. - ///< - sopResizeV, ///< Resize vertical scanline. - ///< - sopDitherAndUnpackH, ///< Dither and unpack horizontal scanline. - ///< - sopUnpackH ///< Unpack horizontal scanline. - ///< - }; - - /** - * Function initializes *this thread data object and assigns certain - * variables provided by the higher level code. - * - * @param aThreadIndex Index of this thread data (0-based). - * @param aThreadCount Total number of threads used during processing. - * @param aSteps Filtering steps. - * @param aVars Image resizer variables. - */ - - void init( const int aThreadIndex, const int aThreadCount, - const CFilterSteps& aSteps, const CImageResizerVars& aVars ) - { - ThreadIndex = aThreadIndex; - ThreadCount = aThreadCount; - Steps = &aSteps; - Vars = &aVars; - } - - /** - * Function initializes scanline processing queue, and updates - * capacities of intermediate buffers. - * - * @param aOp Operation to perform over scanline. - * @param TotalLines The total number of scanlines that will be - * processed by all threads. - * @param aSrcLen Source scanline length in pixels. - * @param aSrcIncr Source scanline buffer increment. Ignored in - * horizontal scanline processing. - * @param aResIncr Resulting scanline buffer increment. Ignored in - * horizontal scanline processing. - */ - - void initScanlineQueue( const EScanlineOperation aOp, - const int TotalLines, const int aSrcLen, const int aSrcIncr = 0, - const int aResIncr = 0 ) - { - const int l = Vars -> BufLen[ 0 ] + Vars -> BufLen[ 1 ]; - - if( Bufs.getCapacity() < l ) - { - Bufs.alloc( l, fpclass :: fpalign ); - } - - BufPtrs[ 0 ] = Bufs + Vars -> BufOffs[ 0 ]; - BufPtrs[ 1 ] = Bufs + Vars -> BufLen[ 0 ] + Vars -> BufOffs[ 1 ]; - - int j; - int ml = 0; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - - if( fs.ResampleFactor == 0 && - ml < fs.FltBank -> getFilterLen() ) - { - ml = fs.FltBank -> getFilterLen(); - } - } - - TmpFltBuf.alloc( ml, fpclass :: fpalign ); - ScanlineOp = aOp; - SrcLen = aSrcLen; - SrcIncr = aSrcIncr; - ResIncr = aResIncr; - QueueLen = 0; - Queue.increaseCapacity(( TotalLines + ThreadCount - 1 ) / - ThreadCount, false ); - } - - /** - * Function adds a scanline to the queue buffer. The - * initScanlineQueue() function should be called before calling this - * function. The number of calls to this add function should not - * exceed the TotalLines spread over all threads. - * - * @param SrcBuf Source scanline buffer. - * @param ResBuf Resulting scanline buffer. - */ - - void addScanlineToQueue( void* const SrcBuf, void* const ResBuf ) - { - Queue[ QueueLen ].SrcBuf = SrcBuf; - Queue[ QueueLen ].ResBuf = ResBuf; - QueueLen++; - } - - /** - * Function processes all queued scanlines. - */ - - void processScanlineQueue() - { - int i; - - switch( ScanlineOp ) - { - case sopResizeH: - { - for( i = 0; i < QueueLen; i++ ) - { - resizeScanlineH( (Tin*) Queue[ i ].SrcBuf, - (fptype*) Queue[ i ].ResBuf ); - } - - break; - } - - case sopResizeV: - { - for( i = 0; i < QueueLen; i++ ) - { - resizeScanlineV( (fptype*) Queue[ i ].SrcBuf, - (fptype*) Queue[ i ].ResBuf ); - } - - break; - } - - case sopDitherAndUnpackH: - { - if( Vars -> UseSRGBGamma ) - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: applySRGBGamma( - (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); - - Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - else - { - for( i = 0; i < QueueLen; i++ ) - { - Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - - break; - } - - case sopUnpackH: - { - if( Vars -> UseSRGBGamma ) - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: applySRGBGamma( - (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - else - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - - break; - } - } - } - - /** - * Function returns ditherer object associated with *this thread data - * object. - */ - - CDitherer& getDitherer() - { - return( Ditherer ); - } - - private: - int ThreadIndex; ///< Thread index. - ///< - int ThreadCount; ///< Thread count. - ///< - const CFilterSteps* Steps; ///< Filtering steps. - ///< - const CImageResizerVars* Vars; ///< Image resizer variables. - ///< - CBuffer< fptype > Bufs; ///< Flip-flop intermediate buffers. - ///< - fptype* BufPtrs[ 3 ]; ///< Flip-flop buffer pointers (referenced by - ///< filtering step's InBuf and OutBuf indices). - ///< - CBuffer< fptype > TmpFltBuf; ///< Temporary buffer used in the - ///< doResize() function, aligned by fpclass :: fpalign. - ///< - EScanlineOperation ScanlineOp; ///< Operation to perform over - ///< scanline. - ///< - int SrcLen; ///< Source scanline length in the last queue. - ///< - int SrcIncr; ///< Source scanline buffer increment in the last queue. - ///< - int ResIncr; ///< Resulting scanline buffer increment in the last - ///< queue. - ///< - CDitherer Ditherer; ///< Ditherer object to use. - ///< - - /** - * @brief Scanline processing queue item. - * - * Scanline processing queue item. - */ - - struct CQueueItem - { - void* SrcBuf; ///< Source scanline buffer, will by typecasted to - ///< Tin or fptype*. - ///< - void* ResBuf; ///< Resulting scanline buffer, will by typecasted - ///< to Tout or fptype*. - ///< - }; - - CBuffer< CQueueItem > Queue; ///< Scanline processing queue. - ///< - int QueueLen; ///< Queue length. - ///< - - /** - * Function resizes a single horizontal scanline. - * - * @param SrcBuf Source scanline buffer. Can be either horizontal or - * vertical. - * @param ResBuf Resulting scanline buffer. - */ - - void resizeScanlineH( const Tin* const SrcBuf, fptype* const ResBuf ) - { - const CFilterStep& fs0 = (*Steps)[ 0 ]; - - fs0.packScanline( SrcBuf, BufPtrs[ 0 ], SrcLen ); - BufPtrs[ 2 ] = ResBuf; - - fptype ElBiases[ 4 ]; - fs0.calcScanlineBias( BufPtrs[ 0 ], SrcLen, ElBiases ); - fs0.unbiasScanline( BufPtrs[ 0 ], SrcLen, ElBiases ); - - int j; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - fs.prepareInBuf( BufPtrs[ fs.InBuf ]); - const int DstIncr = - ( Vars -> packmode == 0 ? Vars -> ElCount : 1 ); - - if( fs.ResampleFactor != 0 ) - { - if( fs.IsUpsample ) - { - fs.doUpsample( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ]); - } - else - { - fs.doFilter( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr ); - } - } - else - { - if( Vars -> IsResize2 ) - { - fs.doResize2( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - else - { - fs.doResize( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - } - } - } - - /** - * Function resizes a single vertical scanline. - * - * @param SrcBuf Source scanline buffer. Can be either horizontal or - * vertical. - * @param ResBuf Resulting scanline buffer. - */ - - void resizeScanlineV( const fptype* const SrcBuf, - fptype* const ResBuf ) - { - const CFilterStep& fs0 = (*Steps)[ 0 ]; - - fs0.convertVtoH( SrcBuf, BufPtrs[ 0 ], SrcLen, SrcIncr ); - BufPtrs[ 2 ] = ResBuf; - - fptype ElBiases[ 4 ]; - fs0.calcScanlineBias( BufPtrs[ 0 ], SrcLen, ElBiases ); - fs0.unbiasScanline( BufPtrs[ 0 ], SrcLen, ElBiases ); - - int j; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - fs.prepareInBuf( BufPtrs[ fs.InBuf ]); - const int DstIncr = ( fs.OutBuf == 2 ? ResIncr : - ( Vars -> packmode == 0 ? Vars -> ElCount : 1 )); - - if( fs.ResampleFactor != 0 ) - { - if( fs.IsUpsample ) - { - fs.doUpsample( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ]); - } - else - { - fs.doFilter( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr ); - } - } - else - { - if( Vars -> IsResize2 ) - { - fs.doResize2( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - else - { - fs.doResize( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - } - } - } - }; -}; - -#undef AVIR_PI -#undef AVIR_PId2 -#undef AVIR_NOCTOR - -} // namespace avir - -#endif // AVIR_CIMAGERESIZER_INCLUDED diff --git a/libraries/Camera/examples/GigaCameraDisplay/display.cpp b/libraries/Camera/examples/GigaCameraDisplay/display.cpp deleted file mode 100644 index 4d4b6d4e4..000000000 --- a/libraries/Camera/examples/GigaCameraDisplay/display.cpp +++ /dev/null @@ -1,351 +0,0 @@ -//#include "Types.h" -#include "Arduino.h" - - -/* Command2 BKx selection command */ -#define DSI_CMD2BKX_SEL 0xFF -#define DSI_CMD2BK1_SEL 0x11 -#define DSI_CMD2BK0_SEL 0x10 -#define DSI_CMD2BKX_SEL_NONE 0x00 - -/* Command2, BK0 commands */ -#define DSI_CMD2_BK0_PVGAMCTRL 0xB0 /* Positive Voltage Gamma Control */ -#define DSI_CMD2_BK0_NVGAMCTRL 0xB1 /* Negative Voltage Gamma Control */ -#define DSI_CMD2_BK0_LNESET 0xC0 /* Display Line setting */ -#define DSI_CMD2_BK0_PORCTRL 0xC1 /* Porch control */ -#define DSI_CMD2_BK0_INVSEL 0xC2 /* Inversion selection, Frame Rate Control */ - -/* Command2, BK1 commands */ -#define DSI_CMD2_BK1_VRHS 0xB0 /* Vop amplitude setting */ -#define DSI_CMD2_BK1_VCOM 0xB1 /* VCOM amplitude setting */ -#define DSI_CMD2_BK1_VGHSS 0xB2 /* VGH Voltage setting */ -#define DSI_CMD2_BK1_TESTCMD 0xB3 /* TEST Command Setting */ -#define DSI_CMD2_BK1_VGLS 0xB5 /* VGL Voltage setting */ -#define DSI_CMD2_BK1_PWCTLR1 0xB7 /* Power Control 1 */ -#define DSI_CMD2_BK1_PWCTLR2 0xB8 /* Power Control 2 */ -#define DSI_CMD2_BK1_SPD1 0xC1 /* Source pre_drive timing set1 */ -#define DSI_CMD2_BK1_SPD2 0xC2 /* Source EQ2 Setting */ -#define DSI_CMD2_BK1_MIPISET1 0xD0 /* MIPI Setting 1 */ - -#define MIPI_DCS_SOFT_RESET 0x01 -#define MIPI_DCS_EXIT_SLEEP_MODE 0x11 - -#ifndef U16 -#define U16 uint16_t -#endif - -#define SSD_MODE(a,b) -#define Set_POWER(a,b,c,d) -#define Set_STANDBY() -#define Set_BOOST(a,b,c,d) -#define Set_RESET(a,b) -#define SSD_LANE(a,b) - -extern DSI_HandleTypeDef dsi; -#define hdsi_eval dsi - -#define LCD_ST7701_ID 0x00 // VC (Virtual channel, for using muliple displays) - -#define Delay(x) delay(x) - -uint8_t BUFFER[8]; -//////////////////////////////////////////////////////// -// Procedure: DCS_Short_Write_NP -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void DCS_Short_Write_NP(uint8_t data0) -{ -// HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_SHORT_PKT_WRITE_P0, data0, 0x00); // DSI_DCS_SHORT_PKT_WRITE_P0 - Serial.print("before DCS_Short_Write_NP "); - Serial.println(millis()); - HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_SHORT_PKT_WRITE_P1, data0, 0x00); // DSI_DCS_SHORT_PKT_WRITE_P0 - Serial.print("after "); - Serial.println(millis()); -} - -//////////////////////////////////////////////////////// -// Procedure: -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void Generic_Short_Write_1P (uint8_t data0, uint8_t data1) -{ -Serial.print("before Generic_Short_Write_1P "); - Serial.println(millis()); - HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_GEN_SHORT_PKT_WRITE_P1, data0, data1); -Serial.print("after "); - Serial.println(millis()); -} - - -//////////////////////////////////////////////////////// -// Procedure: -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void Generic_Long_Write(uint8_t* pdata, int length) -{ - uint8_t data_buf[19] = {0}; // data_buf size with command(*pdata) = 20 so data is alligned 4 - uint8_t data_length = length- 1; - - if (data_length > sizeof(data_buf)) - return; - - memcpy(data_buf, pdata+1, data_length); -// HAL_DSI_LongWrite(&hdsi_eval, LCD_ST7701_ID, DSI_GEN_LONG_PKT_WRITE, data_length, *pdata, data_buf); -Serial.print("before Generic_Long_Write "); - Serial.println(millis()); - HAL_DSI_LongWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_LONG_PKT_WRITE, data_length, *pdata, data_buf); -Serial.print("after "); - Serial.println(millis()); -} -//////////////////////////////////////////////////////// -// Procedure: DCS_Short_Read_NP -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void DCS_Short_Read_NP(uint8_t data0, int length, uint8_t* p_data) -{ - HAL_DSI_Read(&hdsi_eval, LCD_ST7701_ID, p_data, length, DSI_DCS_SHORT_PKT_READ, data0, NULL); -} - -//------------------------------------------------------------------------- -- -// Example: -// Model - HSD040B8W9 -// IC - ST7701 -// Width - 480 -// Height - 800 -// Author - Huangyu(Bitland) -// History: -// V01 2015/05/18 -// -// Disclaimer: -// This C source code is intended as a design reference -// which illustrates how these types of functions can be implemented. -// It is the user's responsibility to verify their design for -// consistency and functionality through the use of formal -// verification methods. LCD Studio provides no warranty regarding the use -// or functionality of this code. -//-------------------------------------------------------------------------------------- -const U16 _E5[17] = {0xE5,0x0E,0x2D,0xA0,0xa0,0x10,0x2D,0xA0,0xA0,0x0A,0x2D,0xA0,0xA0,0x0C,0x2D,0xA0,0xA0}; -const U16 _E8[17] = {0xE8,0x0D,0x2D,0xA0,0xA0,0x0F,0x2D,0xA0,0xA0,0x09,0x2D,0xA0,0xA0,0x0B,0x2D,0xA0,0xA0}; -const U16 _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA}; - - -/**************************************************/ -// I2C power module controller -/**************************************************/ - -void DisplayOn() -{ - Set_POWER(1,1,1,1);//1.8V ON, 2.8V ON, 5V ON, BL ON - -} - - -// -void PowerOffSequence() -{ - DCS_Short_Write_NP(0x28); - Delay(200); - DCS_Short_Write_NP(0x10); - Delay(100); - Set_STANDBY();//Video transfer stop - Delay(50); - - Set_RESET(1,0);//MIPI RESET 1, LCD RESET 0 - Delay(50); - Set_RESET(0,0);//MIPI RESET 0, LCD RESET 0 - Delay(50); - - Set_POWER(1,1,0,1);//1.8V ON, 2.8V ON, 5V OFF, BL ON - Delay(50); - - Set_BOOST(5.00, 5.00, 0x81, 50);//VDD, VEE, OFF:VDD->VEE, 10ms - Delay(50); - - Set_POWER(1,0,0,1);//1.8V ON, 2.8V OFF, 5V OFF, BL ON - Delay(100); - Set_POWER(0,0,0,0);//1.8V OFF, 2.8V OFF, 5V OFF, BL OFF - -} - -/**************************************************/ -// Read function (Option) -/**************************************************/ -// -void ReadOperation() -{ - //Clean memory: BUFFER - memset(BUFFER, 0, sizeof(BUFFER));//BUFFER size: 8 Bytes - - //Read value to BUFFER - DCS_Short_Read_NP(0xDA, 1, BUFFER+0); - DCS_Short_Read_NP(0xDB, 1, BUFFER+1); - DCS_Short_Read_NP(0xDC, 1,BUFFER+2); -} -volatile int LENGTH; -#define ST7701_DSI(mipi_dsi, seq...) \ -do { \ - const u8 d[] = { seq }; \ - LENGTH = ARRAY_SIZE(d); \ -}while(0) - - -void LCD_ST7701_Init(void) -{ - pinMode(PD_3, OUTPUT); - pinMode(PD_3, HIGH); - delay(200); - pinMode(PD_3, LOW); - delay(200); - pinMode(PD_3, HIGH); - - DCS_Short_Write_NP(MIPI_DCS_SOFT_RESET); - Delay(200); - - Serial.println("here"); - - //ST7701S+IVO5.0 - DCS_Short_Write_NP(MIPI_DCS_EXIT_SLEEP_MODE); - - // tesrt - - //------------------------------------------Bank0 Setting----------------------------------------------------// - //------------------------------------Display Control setting----------------------------------------------// - Delay(800); - - const uint8_t Display_Control_0[] = {0xFF,0x77,0x01,0x00,0x00,0x10}; //Generic_Long_Write_5P - const uint8_t Display_Control_1[] = {0xC0,0x63,0x00}; //Generic_Long_Write_2P - const uint8_t Display_Control_2[] = {0xC1,0x11,0x02}; - const uint8_t Display_Control_3[] = {0xC2,0x01,0x08}; - const uint8_t Display_Control_4[] = {0xCC,0x18}; - // const uint8_t Display_Control_5[] = {0x3a,0x50}; // color mode 565:50h 666:60h 888:70h - - Generic_Long_Write((uint8_t*)Display_Control_0, sizeof(Display_Control_0)); - Generic_Long_Write((uint8_t*)Display_Control_1, sizeof(Display_Control_1)); - Generic_Long_Write((uint8_t*)Display_Control_2, sizeof(Display_Control_2)); - Generic_Long_Write((uint8_t*)Display_Control_3, sizeof(Display_Control_3)); - Generic_Long_Write((uint8_t*)Display_Control_4, sizeof(Display_Control_4)); - - //-------------------------------------Gamma Cluster Setting-------------------------------------------// -// Ver1 const uint8_t _B0[17] = {0xB0,0x00, 0x0E, 0x15, 0x0F, 0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,0x2B, 0x34, 0x1F}; - const uint8_t _B0[] = {0xB0,0x40, 0xc9, 0x91, 0x0d, - 0x12, 0x07, 0x02, 0x09, 0x09, 0x1f, 0x04, 0x50, 0x0f, - 0xe4, 0x29, 0xdf}; - -// Ver1 const uint8_t _B1[17] = {0xB1, 0x00, 0x0E, 0x95, 0x0F,0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,0x2C, 0x34, 0x1F}; - const uint8_t _B1[] = {0xB1, 0x40, 0xcb, 0xd0, 0x11, - 0x92, 0x07, 0x00, 0x08, 0x07, 0x1c, 0x06, 0x53, 0x12, - 0x63, 0xeb, 0xdf}; - - Generic_Long_Write((uint8_t*)_B0, sizeof(_B0)); - Generic_Long_Write((uint8_t*)_B1, sizeof(_B1)); - //---------------------------------------End Gamma Setting----------------------------------------------// - //------------------------------------End Display Control setting----------------------------------------// - //-----------------------------------------Bank0 Setting End---------------------------------------------// - //-------------------------------------------Bank1 Setting---------------------------------------------------// - //-------------------------------- Power Control Registers Initial --------------------------------------// - const uint8_t _FF1[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BK1_SEL}; - Generic_Long_Write ((uint8_t*)_FF1, sizeof(_FF1)); - - -// Generic_Short_Write_1P (DSI_CMD2_BK1_VRHS,0x50); - Generic_Short_Write_1P (DSI_CMD2_BK1_VRHS,0x65); - //-------------------------------------------Vcom Setting---------------------------------------------------// -// Generic_Short_Write_1P (DSI_CMD2_BK1_VCOM,0x68); - Generic_Short_Write_1P (DSI_CMD2_BK1_VCOM,0x34); - //-----------------------------------------End Vcom Setting-----------------------------------------------// -// Generic_Short_Write_1P (DSI_CMD2_BK1_VGHSS,0x07); - Generic_Short_Write_1P (DSI_CMD2_BK1_VGHSS,0x87); - - Generic_Short_Write_1P (DSI_CMD2_BK1_TESTCMD,0x80); -// Generic_Short_Write_1P (DSI_CMD2_BK1_VGLS,0x47); - Generic_Short_Write_1P (DSI_CMD2_BK1_VGLS,0x49); - Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR1,0x85); -// Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR2,0x21); - Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR2,0x20); - Generic_Short_Write_1P (0xB9,0x10); - Generic_Short_Write_1P (DSI_CMD2_BK1_SPD1,0x78); - Generic_Short_Write_1P (DSI_CMD2_BK1_SPD2,0x78); - Generic_Short_Write_1P (DSI_CMD2_BK1_MIPISET1,0x88); - //---------------------------------End Power Control Registers Initial -------------------------------// - Delay(100); - //---------------------------------------------GIP Setting----------------------------------------------------// - const uint8_t _E0[] = {0xE0,0x00,0x00,0x02}; - Generic_Long_Write((uint8_t*)_E0, sizeof(_E0)); - //----------------------------------GIP---------------------------------------------------- - const uint8_t _E1[] = {0xE1,0x08,0x00,0x0A,0x00,0x07,0x00,0x09,0x00,0x00,0x33,0x33}; - const uint8_t _E2[] = {0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - Generic_Long_Write((uint8_t*)_E1, sizeof(_E1)); - Generic_Long_Write((uint8_t*)_E2, sizeof(_E2)); - - //-------------------------------------------------------------------------------------- - const uint8_t _E3[] = {0xE3,0x00,0x00,0x33,0x33}; - const uint8_t _E4[] = {0xE4,0x44,0x44}; - Generic_Long_Write((uint8_t*)_E3, sizeof(_E3)); - Generic_Long_Write((uint8_t*)_E4, sizeof(_E4)); - -// const uint8_t _E5[] = {0xE5,0x0E,0x2D,0xA0,0xa0,0x10,0x2D,0xA0,0xA0,0x0A,0x2D,0xA0,0xA0,0x0C,0x2D,0xA0,0xA0}; - const uint8_t _E5[] = {0xE5,0x0E,0x60,0xA0,0xa0,0x10,0x60,0xA0,0xA0,0x0A,0x60,0xA0,0xA0,0x0C,0x60,0xA0,0xA0}; - Generic_Long_Write((uint8_t*)_E5, sizeof(_E5)); - - const uint8_t _E6[] = {0xE6,0x00,0x00,0x33,0x33}; - const uint8_t _E7[] = {0xE7,0x44,0x44}; - Generic_Long_Write((uint8_t*)_E6, sizeof(_E6)); - Generic_Long_Write((uint8_t*)_E7, sizeof(_E7)); - -// const uint8_t _E8[] = {0xE8,0x0D,0x2D,0xA0,0xA0,0x0F,0x2D,0xA0,0xA0,0x09,0x2D,0xA0,0xA0,0x0B,0x2D,0xA0,0xA0}; - const uint8_t _E8[] = {0xE8,0x0D,0x60,0xA0,0xA0,0x0F,0x60,0xA0,0xA0,0x09,0x60,0xA0,0xA0,0x0B,0x60,0xA0,0xA0}; - Generic_Long_Write((uint8_t*)_E8, sizeof(_E8)); - - const uint8_t _EB[] = {0xEB,0x02,0x01,0xE4,0xE4,0x44,0x00,0x40}; - const uint8_t _EC[] = {0xEC,0x02,0x01}; - Generic_Long_Write((uint8_t*)_EB, sizeof(_EB)); - Generic_Long_Write((uint8_t*)_EC, sizeof(_EC)); - - const uint8_t _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA}; - Generic_Long_Write((uint8_t*)_ED, sizeof(_ED)); - - //--------------------------------------------End GIP Setting-----------------------------------------------// - //------------------------------ Power Control Registers Initial End-----------------------------------// - //------------------------------------------Bank1 Setting----------------------------------------------------// - const uint8_t _FF2[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BKX_SEL_NONE}; - Generic_Long_Write ((uint8_t*)_FF2, sizeof(_FF2)); - - Delay(10); - DCS_Short_Write_NP(0x29); - Delay(200); - - - SSD_MODE(0,1); - -// ReadOperation(); - /* - Read_ADC(2.80,1,0.2);//��ȡӲ��ID ��ѹ��Χ0V - 3.3V - - if(!memcmp("0x01")) //�жϵ�ѹ���ڵķ�Χ�� - { - Set_TEXT(0, 1, 0x22);//��Ļ��ʾ��ɫ������������ - } - else - { - Set_TEXT(0, 0, 0x01);//Draw Text: "PASS" - - } - - */ -} diff --git a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md new file mode 100644 index 000000000..ca6928207 --- /dev/null +++ b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md @@ -0,0 +1,35 @@ +# Managing CA Certs for TLS connections + +## Generating `certificates.h` from PEM file: + +> [!NOTE] +> Pre-requisites: `xxd` from `vim` packages or standalone +``` +xxd -i cacert.pem -n cacert_pem | sed 's/^unsigned/const unsigned/g' > certificates.h +``` + +## Getting PEM file from `certificates.h` + +> [!NOTE] +> Pre-requisites: `xxd`, GNU Tools (Use g-tools on MacOS: e.g., `gtail`, `ghead`) +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p > cacert.pem +``` +## Listing certifcates in `certificates.h` + +> [!NOTE] +> Pre-requisites: `openssl` + +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p > cacert.pem +openssl crl2pkcs7 -nocrl -certfile cacert.pem | openssl pkcs7 -print_certs | grep '^subject' +``` + +## Adding a new root certificate to `certificates.h` + +> [!Note] +> The PEM file for the root CA to add, e.g., `new_root.pem` + +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p | cat - new_root.pem | xxd -n cacert_pem -i | sed 's/^unsigned/const unsigned/g' > certificates.h +``` diff --git a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h index 44fdeb168..768aa670c 100644 --- a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h +++ b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h @@ -5267,6 +5267,167 @@ const unsigned char cacert_pem[] = { 0x56, 0x39, 0x70, 0x41, 0x35, 0x47, 0x59, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x0a, 0x00 + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, + 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x61, 0x7a, 0x43, + 0x43, 0x41, 0x31, 0x4f, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, + 0x52, 0x41, 0x49, 0x49, 0x51, 0x7a, 0x37, 0x44, 0x53, 0x51, 0x4f, 0x4e, + 0x5a, 0x52, 0x47, 0x50, 0x67, 0x75, 0x32, 0x4f, 0x43, 0x69, 0x77, 0x41, + 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, + 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x77, 0x0a, 0x54, 0x7a, + 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, + 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x4b, 0x54, 0x41, 0x6e, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x49, 0x45, 0x6c, 0x75, 0x64, 0x47, + 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x4e, 0x6c, 0x59, 0x33, + 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x4a, 0x6c, 0x63, 0x32, + 0x56, 0x68, 0x0a, 0x63, 0x6d, 0x4e, 0x6f, 0x49, 0x45, 0x64, 0x79, 0x62, + 0x33, 0x56, 0x77, 0x4d, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x44, 0x45, 0x77, 0x78, 0x4a, 0x55, 0x31, 0x4a, 0x48, 0x49, + 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x57, 0x44, 0x45, 0x77, 0x48, + 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x55, 0x77, 0x4e, 0x6a, 0x41, 0x30, 0x4d, + 0x54, 0x45, 0x77, 0x4e, 0x44, 0x4d, 0x34, 0x0a, 0x57, 0x68, 0x63, 0x4e, + 0x4d, 0x7a, 0x55, 0x77, 0x4e, 0x6a, 0x41, 0x30, 0x4d, 0x54, 0x45, 0x77, + 0x4e, 0x44, 0x4d, 0x34, 0x57, 0x6a, 0x42, 0x50, 0x4d, 0x51, 0x73, 0x77, + 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, + 0x55, 0x7a, 0x45, 0x70, 0x4d, 0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, + 0x43, 0x68, 0x4d, 0x67, 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x75, + 0x0a, 0x5a, 0x58, 0x51, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, + 0x70, 0x64, 0x48, 0x6b, 0x67, 0x55, 0x6d, 0x56, 0x7a, 0x5a, 0x57, 0x46, + 0x79, 0x59, 0x32, 0x67, 0x67, 0x52, 0x33, 0x4a, 0x76, 0x64, 0x58, 0x41, + 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, + 0x54, 0x44, 0x45, 0x6c, 0x54, 0x55, 0x6b, 0x63, 0x67, 0x55, 0x6d, 0x39, + 0x76, 0x64, 0x43, 0x42, 0x59, 0x0a, 0x4d, 0x54, 0x43, 0x43, 0x41, 0x69, + 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, + 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, + 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6f, 0x43, 0x67, 0x67, + 0x49, 0x42, 0x41, 0x4b, 0x33, 0x6f, 0x4a, 0x48, 0x50, 0x30, 0x46, 0x44, + 0x66, 0x7a, 0x6d, 0x35, 0x34, 0x72, 0x56, 0x79, 0x67, 0x63, 0x0a, 0x68, + 0x37, 0x37, 0x63, 0x74, 0x39, 0x38, 0x34, 0x6b, 0x49, 0x78, 0x75, 0x50, + 0x4f, 0x5a, 0x58, 0x6f, 0x48, 0x6a, 0x33, 0x64, 0x63, 0x4b, 0x69, 0x2f, + 0x76, 0x56, 0x71, 0x62, 0x76, 0x59, 0x41, 0x54, 0x79, 0x6a, 0x62, 0x33, + 0x6d, 0x69, 0x47, 0x62, 0x45, 0x53, 0x54, 0x74, 0x72, 0x46, 0x6a, 0x2f, + 0x52, 0x51, 0x53, 0x61, 0x37, 0x38, 0x66, 0x30, 0x75, 0x6f, 0x78, 0x6d, + 0x79, 0x46, 0x2b, 0x0a, 0x30, 0x54, 0x4d, 0x38, 0x75, 0x6b, 0x6a, 0x31, + 0x33, 0x58, 0x6e, 0x66, 0x73, 0x37, 0x6a, 0x2f, 0x45, 0x76, 0x45, 0x68, + 0x6d, 0x6b, 0x76, 0x42, 0x69, 0x6f, 0x5a, 0x78, 0x61, 0x55, 0x70, 0x6d, + 0x5a, 0x6d, 0x79, 0x50, 0x66, 0x6a, 0x78, 0x77, 0x76, 0x36, 0x30, 0x70, + 0x49, 0x67, 0x62, 0x7a, 0x35, 0x4d, 0x44, 0x6d, 0x67, 0x4b, 0x37, 0x69, + 0x53, 0x34, 0x2b, 0x33, 0x6d, 0x58, 0x36, 0x55, 0x0a, 0x41, 0x35, 0x2f, + 0x54, 0x52, 0x35, 0x64, 0x38, 0x6d, 0x55, 0x67, 0x6a, 0x55, 0x2b, 0x67, + 0x34, 0x72, 0x6b, 0x38, 0x4b, 0x62, 0x34, 0x4d, 0x75, 0x30, 0x55, 0x6c, + 0x58, 0x6a, 0x49, 0x42, 0x30, 0x74, 0x74, 0x6f, 0x76, 0x30, 0x44, 0x69, + 0x4e, 0x65, 0x77, 0x4e, 0x77, 0x49, 0x52, 0x74, 0x31, 0x38, 0x6a, 0x41, + 0x38, 0x2b, 0x6f, 0x2b, 0x75, 0x33, 0x64, 0x70, 0x6a, 0x71, 0x2b, 0x73, + 0x57, 0x0a, 0x54, 0x38, 0x4b, 0x4f, 0x45, 0x55, 0x74, 0x2b, 0x7a, 0x77, + 0x76, 0x6f, 0x2f, 0x37, 0x56, 0x33, 0x4c, 0x76, 0x53, 0x79, 0x65, 0x30, + 0x72, 0x67, 0x54, 0x42, 0x49, 0x6c, 0x44, 0x48, 0x43, 0x4e, 0x41, 0x79, + 0x6d, 0x67, 0x34, 0x56, 0x4d, 0x6b, 0x37, 0x42, 0x50, 0x5a, 0x37, 0x68, + 0x6d, 0x2f, 0x45, 0x4c, 0x4e, 0x4b, 0x6a, 0x44, 0x2b, 0x4a, 0x6f, 0x32, + 0x46, 0x52, 0x33, 0x71, 0x79, 0x48, 0x0a, 0x42, 0x35, 0x54, 0x30, 0x59, + 0x33, 0x48, 0x73, 0x4c, 0x75, 0x4a, 0x76, 0x57, 0x35, 0x69, 0x42, 0x34, + 0x59, 0x6c, 0x63, 0x4e, 0x48, 0x6c, 0x73, 0x64, 0x75, 0x38, 0x37, 0x6b, + 0x47, 0x4a, 0x35, 0x35, 0x74, 0x75, 0x6b, 0x6d, 0x69, 0x38, 0x6d, 0x78, + 0x64, 0x41, 0x51, 0x34, 0x51, 0x37, 0x65, 0x32, 0x52, 0x43, 0x4f, 0x46, + 0x76, 0x75, 0x33, 0x39, 0x36, 0x6a, 0x33, 0x78, 0x2b, 0x55, 0x43, 0x0a, + 0x42, 0x35, 0x69, 0x50, 0x4e, 0x67, 0x69, 0x56, 0x35, 0x2b, 0x49, 0x33, + 0x6c, 0x67, 0x30, 0x32, 0x64, 0x5a, 0x37, 0x37, 0x44, 0x6e, 0x4b, 0x78, + 0x48, 0x5a, 0x75, 0x38, 0x41, 0x2f, 0x6c, 0x4a, 0x42, 0x64, 0x69, 0x42, + 0x33, 0x51, 0x57, 0x30, 0x4b, 0x74, 0x5a, 0x42, 0x36, 0x61, 0x77, 0x42, + 0x64, 0x70, 0x55, 0x4b, 0x44, 0x39, 0x6a, 0x66, 0x31, 0x62, 0x30, 0x53, + 0x48, 0x7a, 0x55, 0x76, 0x0a, 0x4b, 0x42, 0x64, 0x73, 0x30, 0x70, 0x6a, + 0x42, 0x71, 0x41, 0x6c, 0x6b, 0x64, 0x32, 0x35, 0x48, 0x4e, 0x37, 0x72, + 0x4f, 0x72, 0x46, 0x6c, 0x65, 0x61, 0x4a, 0x31, 0x2f, 0x63, 0x74, 0x61, + 0x4a, 0x78, 0x51, 0x5a, 0x42, 0x4b, 0x54, 0x35, 0x5a, 0x50, 0x74, 0x30, + 0x6d, 0x39, 0x53, 0x54, 0x4a, 0x45, 0x61, 0x64, 0x61, 0x6f, 0x30, 0x78, + 0x41, 0x48, 0x30, 0x61, 0x68, 0x6d, 0x62, 0x57, 0x6e, 0x0a, 0x4f, 0x6c, + 0x46, 0x75, 0x68, 0x6a, 0x75, 0x65, 0x66, 0x58, 0x4b, 0x6e, 0x45, 0x67, + 0x56, 0x34, 0x57, 0x65, 0x30, 0x2b, 0x55, 0x58, 0x67, 0x56, 0x43, 0x77, + 0x4f, 0x50, 0x6a, 0x64, 0x41, 0x76, 0x42, 0x62, 0x49, 0x2b, 0x65, 0x30, + 0x6f, 0x63, 0x53, 0x33, 0x4d, 0x46, 0x45, 0x76, 0x7a, 0x47, 0x36, 0x75, + 0x42, 0x51, 0x45, 0x33, 0x78, 0x44, 0x6b, 0x33, 0x53, 0x7a, 0x79, 0x6e, + 0x54, 0x6e, 0x0a, 0x6a, 0x68, 0x38, 0x42, 0x43, 0x4e, 0x41, 0x77, 0x31, + 0x46, 0x74, 0x78, 0x4e, 0x72, 0x51, 0x48, 0x75, 0x73, 0x45, 0x77, 0x4d, + 0x46, 0x78, 0x49, 0x74, 0x34, 0x49, 0x37, 0x6d, 0x4b, 0x5a, 0x39, 0x59, + 0x49, 0x71, 0x69, 0x6f, 0x79, 0x6d, 0x43, 0x7a, 0x4c, 0x71, 0x39, 0x67, + 0x77, 0x51, 0x62, 0x6f, 0x6f, 0x4d, 0x44, 0x51, 0x61, 0x48, 0x57, 0x42, + 0x66, 0x45, 0x62, 0x77, 0x72, 0x62, 0x77, 0x0a, 0x71, 0x48, 0x79, 0x47, + 0x4f, 0x30, 0x61, 0x6f, 0x53, 0x43, 0x71, 0x49, 0x33, 0x48, 0x61, 0x61, + 0x64, 0x72, 0x38, 0x66, 0x61, 0x71, 0x55, 0x39, 0x47, 0x59, 0x2f, 0x72, + 0x4f, 0x50, 0x4e, 0x6b, 0x33, 0x73, 0x67, 0x72, 0x44, 0x51, 0x6f, 0x6f, + 0x2f, 0x2f, 0x66, 0x62, 0x34, 0x68, 0x56, 0x43, 0x31, 0x43, 0x4c, 0x51, + 0x4a, 0x31, 0x33, 0x68, 0x65, 0x66, 0x34, 0x59, 0x35, 0x33, 0x43, 0x49, + 0x0a, 0x72, 0x55, 0x37, 0x6d, 0x32, 0x59, 0x73, 0x36, 0x78, 0x74, 0x30, + 0x6e, 0x55, 0x57, 0x37, 0x2f, 0x76, 0x47, 0x54, 0x31, 0x4d, 0x30, 0x4e, + 0x50, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x51, 0x6a, 0x42, + 0x41, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, + 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, + 0x50, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, + 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, + 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, + 0x52, 0x35, 0x74, 0x46, 0x6e, 0x6d, 0x65, 0x37, 0x62, 0x6c, 0x35, 0x41, + 0x46, 0x7a, 0x67, 0x41, 0x69, 0x49, 0x79, 0x42, 0x70, 0x59, 0x39, 0x75, + 0x6d, 0x62, 0x62, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x0a, 0x68, + 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, + 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x56, 0x52, 0x39, 0x59, 0x71, + 0x62, 0x79, 0x79, 0x71, 0x46, 0x44, 0x51, 0x44, 0x4c, 0x48, 0x59, 0x47, + 0x6d, 0x6b, 0x67, 0x4a, 0x79, 0x6b, 0x49, 0x72, 0x47, 0x46, 0x31, 0x58, + 0x49, 0x70, 0x75, 0x2b, 0x49, 0x4c, 0x6c, 0x61, 0x53, 0x2f, 0x56, 0x39, + 0x6c, 0x5a, 0x4c, 0x0a, 0x75, 0x62, 0x68, 0x7a, 0x45, 0x46, 0x6e, 0x54, + 0x49, 0x5a, 0x64, 0x2b, 0x35, 0x30, 0x78, 0x78, 0x2b, 0x37, 0x4c, 0x53, + 0x59, 0x4b, 0x30, 0x35, 0x71, 0x41, 0x76, 0x71, 0x46, 0x79, 0x46, 0x57, + 0x68, 0x66, 0x46, 0x51, 0x44, 0x6c, 0x6e, 0x72, 0x7a, 0x75, 0x42, 0x5a, + 0x36, 0x62, 0x72, 0x4a, 0x46, 0x65, 0x2b, 0x47, 0x6e, 0x59, 0x2b, 0x45, + 0x67, 0x50, 0x62, 0x6b, 0x36, 0x5a, 0x47, 0x51, 0x0a, 0x33, 0x42, 0x65, + 0x62, 0x59, 0x68, 0x74, 0x46, 0x38, 0x47, 0x61, 0x56, 0x30, 0x6e, 0x78, + 0x76, 0x77, 0x75, 0x6f, 0x37, 0x37, 0x78, 0x2f, 0x50, 0x79, 0x39, 0x61, + 0x75, 0x4a, 0x2f, 0x47, 0x70, 0x73, 0x4d, 0x69, 0x75, 0x2f, 0x58, 0x31, + 0x2b, 0x6d, 0x76, 0x6f, 0x69, 0x42, 0x4f, 0x76, 0x2f, 0x32, 0x58, 0x2f, + 0x71, 0x6b, 0x53, 0x73, 0x69, 0x73, 0x52, 0x63, 0x4f, 0x6a, 0x2f, 0x4b, + 0x4b, 0x0a, 0x4e, 0x46, 0x74, 0x59, 0x32, 0x50, 0x77, 0x42, 0x79, 0x56, + 0x53, 0x35, 0x75, 0x43, 0x62, 0x4d, 0x69, 0x6f, 0x67, 0x7a, 0x69, 0x55, + 0x77, 0x74, 0x68, 0x44, 0x79, 0x43, 0x33, 0x2b, 0x36, 0x57, 0x56, 0x77, + 0x57, 0x36, 0x4c, 0x4c, 0x76, 0x33, 0x78, 0x4c, 0x66, 0x48, 0x54, 0x6a, + 0x75, 0x43, 0x76, 0x6a, 0x48, 0x49, 0x49, 0x6e, 0x4e, 0x7a, 0x6b, 0x74, + 0x48, 0x43, 0x67, 0x4b, 0x51, 0x35, 0x0a, 0x4f, 0x52, 0x41, 0x7a, 0x49, + 0x34, 0x4a, 0x4d, 0x50, 0x4a, 0x2b, 0x47, 0x73, 0x6c, 0x57, 0x59, 0x48, + 0x62, 0x34, 0x70, 0x68, 0x6f, 0x77, 0x69, 0x6d, 0x35, 0x37, 0x69, 0x61, + 0x7a, 0x74, 0x58, 0x4f, 0x6f, 0x4a, 0x77, 0x54, 0x64, 0x77, 0x4a, 0x78, + 0x34, 0x6e, 0x4c, 0x43, 0x67, 0x64, 0x4e, 0x62, 0x4f, 0x68, 0x64, 0x6a, + 0x73, 0x6e, 0x76, 0x7a, 0x71, 0x76, 0x48, 0x75, 0x37, 0x55, 0x72, 0x0a, + 0x54, 0x6b, 0x58, 0x57, 0x53, 0x74, 0x41, 0x6d, 0x7a, 0x4f, 0x56, 0x79, + 0x79, 0x67, 0x68, 0x71, 0x70, 0x5a, 0x58, 0x6a, 0x46, 0x61, 0x48, 0x33, + 0x70, 0x4f, 0x33, 0x4a, 0x4c, 0x46, 0x2b, 0x6c, 0x2b, 0x2f, 0x2b, 0x73, + 0x4b, 0x41, 0x49, 0x75, 0x76, 0x74, 0x64, 0x37, 0x75, 0x2b, 0x4e, 0x78, + 0x65, 0x35, 0x41, 0x57, 0x30, 0x77, 0x64, 0x65, 0x52, 0x6c, 0x4e, 0x38, + 0x4e, 0x77, 0x64, 0x43, 0x0a, 0x6a, 0x4e, 0x50, 0x45, 0x6c, 0x70, 0x7a, + 0x56, 0x6d, 0x62, 0x55, 0x71, 0x34, 0x4a, 0x55, 0x61, 0x67, 0x45, 0x69, + 0x75, 0x54, 0x44, 0x6b, 0x48, 0x7a, 0x73, 0x78, 0x48, 0x70, 0x46, 0x4b, + 0x56, 0x4b, 0x37, 0x71, 0x34, 0x2b, 0x36, 0x33, 0x53, 0x4d, 0x31, 0x4e, + 0x39, 0x35, 0x52, 0x31, 0x4e, 0x62, 0x64, 0x57, 0x68, 0x73, 0x63, 0x64, + 0x43, 0x62, 0x2b, 0x5a, 0x41, 0x4a, 0x7a, 0x56, 0x63, 0x0a, 0x6f, 0x79, + 0x69, 0x33, 0x42, 0x34, 0x33, 0x6e, 0x6a, 0x54, 0x4f, 0x51, 0x35, 0x79, + 0x4f, 0x66, 0x2b, 0x31, 0x43, 0x63, 0x65, 0x57, 0x78, 0x47, 0x31, 0x62, + 0x51, 0x56, 0x73, 0x35, 0x5a, 0x75, 0x66, 0x70, 0x73, 0x4d, 0x6c, 0x6a, + 0x71, 0x34, 0x55, 0x69, 0x30, 0x2f, 0x31, 0x6c, 0x76, 0x68, 0x2b, 0x77, + 0x6a, 0x43, 0x68, 0x50, 0x34, 0x6b, 0x71, 0x4b, 0x4f, 0x4a, 0x32, 0x71, + 0x78, 0x71, 0x0a, 0x34, 0x52, 0x67, 0x71, 0x73, 0x61, 0x68, 0x44, 0x59, + 0x56, 0x76, 0x54, 0x48, 0x39, 0x77, 0x37, 0x6a, 0x58, 0x62, 0x79, 0x4c, + 0x65, 0x69, 0x4e, 0x64, 0x64, 0x38, 0x58, 0x4d, 0x32, 0x77, 0x39, 0x55, + 0x2f, 0x74, 0x37, 0x79, 0x30, 0x46, 0x66, 0x2f, 0x39, 0x79, 0x69, 0x30, + 0x47, 0x45, 0x34, 0x34, 0x5a, 0x61, 0x34, 0x72, 0x46, 0x32, 0x4c, 0x4e, + 0x39, 0x64, 0x31, 0x31, 0x54, 0x50, 0x41, 0x0a, 0x6d, 0x52, 0x47, 0x75, + 0x6e, 0x55, 0x48, 0x42, 0x63, 0x6e, 0x57, 0x45, 0x76, 0x67, 0x4a, 0x42, + 0x51, 0x6c, 0x39, 0x6e, 0x4a, 0x45, 0x69, 0x55, 0x30, 0x5a, 0x73, 0x6e, + 0x76, 0x67, 0x63, 0x2f, 0x75, 0x62, 0x68, 0x50, 0x67, 0x58, 0x52, 0x52, + 0x34, 0x58, 0x71, 0x33, 0x37, 0x5a, 0x30, 0x6a, 0x34, 0x72, 0x37, 0x67, + 0x31, 0x53, 0x67, 0x45, 0x45, 0x7a, 0x77, 0x78, 0x41, 0x35, 0x37, 0x64, + 0x0a, 0x65, 0x6d, 0x79, 0x50, 0x78, 0x67, 0x63, 0x59, 0x78, 0x6e, 0x2f, + 0x65, 0x52, 0x34, 0x34, 0x2f, 0x4b, 0x4a, 0x34, 0x45, 0x42, 0x73, 0x2b, + 0x6c, 0x56, 0x44, 0x52, 0x33, 0x76, 0x65, 0x79, 0x4a, 0x6d, 0x2b, 0x6b, + 0x58, 0x51, 0x39, 0x39, 0x62, 0x32, 0x31, 0x2f, 0x2b, 0x6a, 0x68, 0x35, + 0x58, 0x6f, 0x73, 0x31, 0x41, 0x6e, 0x58, 0x35, 0x69, 0x49, 0x74, 0x72, + 0x65, 0x47, 0x43, 0x63, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, + 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, + 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; -unsigned int cacert_pem_len = 63218; +const unsigned int cacert_pem_len = 65156; diff --git a/nano.variables b/nano.variables index 1cba7139a..20602833e 100644 --- a/nano.variables +++ b/nano.variables @@ -1,5 +1,5 @@ export FLAVOUR="nano" export VARIANTS=("NANO_RP2040_CONNECT ARDUINO_NANO33BLE") export FQBNS=("nanorp2040connect nano33ble") -export LIBRARIES=("PDM SPI Wire MRI USBHID USBMSD ThreadDebug Scheduler SFU Nano33BLE_System SocketWrapper MLC") +export LIBRARIES=("PDM SPI Wire MRI USBHID USBMIDI USBMSD ThreadDebug Scheduler SFU Nano33BLE_System SocketWrapper MLC") export BOOTLOADERS=("nano33ble") diff --git a/package_full.sh b/package_full.sh index fa84dcd0d..66c09d963 100755 --- a/package_full.sh +++ b/package_full.sh @@ -1,5 +1,5 @@ #Get version from git(hub) tag -export VERSION="4.0.4" +export VERSION="4.0.6" FLAVOURS=`ls *.variables` diff --git a/platform.txt b/platform.txt index a8cae2a71..4ab18ab42 100644 --- a/platform.txt +++ b/platform.txt @@ -4,8 +4,8 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -name=Arduino Mbed OS Boards -version=9.9.9 +name=Arduino Mbed OS Boards +version= # Compile variables # ------------------------ diff --git a/portenta.variables b/portenta.variables index ed2e0973f..8ae4b3f2b 100644 --- a/portenta.variables +++ b/portenta.variables @@ -1,5 +1,5 @@ export FLAVOUR="portenta" export VARIANTS=("PORTENTA_H7_M7 PORTENTA_H7_M4 PORTENTA_X8") export FQBNS=("envie_m7 portenta_x8") -export LIBRARIES=("doom Ethernet MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 Himax_HM0360 PDM Portenta_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib USBHOST mbed-memory-status Portenta_SDCARD Scheduler USBMSD SocketWrapper GSM GPS MCUboot") +export LIBRARIES=("doom Ethernet MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 Himax_HM0360 PDM Arduino_H7_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib USBHOST mbed-memory-status Portenta_SDCARD Scheduler USBMSD USBMIDI SocketWrapper GSM GPS MCUboot Arduino_CAN") export BOOTLOADERS=("PORTENTA_H7") diff --git a/variants/ARDUINO_NANO33BLE/defines.txt b/variants/ARDUINO_NANO33BLE/defines.txt index 0123b4077..0a9037a60 100644 --- a/variants/ARDUINO_NANO33BLE/defines.txt +++ b/variants/ARDUINO_NANO33BLE/defines.txt @@ -1,15 +1,17 @@ -DARM_MATH_CM4 -DBOARD_PCA10056 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 -DCONFIG_GPIO_AS_PINRESET +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -30,10 +32,13 @@ -DFEATURE_BLE=1 -DFEATURE_CRYPTOCELL310=1 -DFEATURE_STORAGE=1 --DMBEDTLS_CONFIG_HW_SUPPORT --DMBED_BUILD_TIMESTAMP=1670863539.4329445 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690446991.0429106 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_CONFIG_HW_SUPPORT -DNRF52840_XXAA -DNRF52_PAN_20 -DSWI_DISABLE0 @@ -59,11 +64,6 @@ -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -DWSF_MAX_HANDLERS=10 --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/ARDUINO_NANO33BLE/includes.txt b/variants/ARDUINO_NANO33BLE/includes.txt index d2a028010..63c35643d 100644 --- a/variants/ARDUINO_NANO33BLE/includes.txt +++ b/variants/ARDUINO_NANO33BLE/includes.txt @@ -128,23 +128,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/ARDUINO_NANO33BLE/libs/libmbed.a b/variants/ARDUINO_NANO33BLE/libs/libmbed.a index 62703cbde..915858f44 100644 Binary files a/variants/ARDUINO_NANO33BLE/libs/libmbed.a and b/variants/ARDUINO_NANO33BLE/libs/libmbed.a differ diff --git a/variants/ARDUINO_NANO33BLE/mbed_config.h b/variants/ARDUINO_NANO33BLE/mbed_config.h index 5cf0ce054..7af2c4570 100644 --- a/variants/ARDUINO_NANO33BLE/mbed_config.h +++ b/variants/ARDUINO_NANO33BLE/mbed_config.h @@ -202,6 +202,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/EDGE_CONTROL/defines.txt b/variants/EDGE_CONTROL/defines.txt index d8ee365dc..0198e4a12 100644 --- a/variants/EDGE_CONTROL/defines.txt +++ b/variants/EDGE_CONTROL/defines.txt @@ -1,6 +1,7 @@ -DARM_MATH_CM4 -DBOARD_PCA10056 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 @@ -8,11 +9,12 @@ -DCOMPONENT_SD=1 -DCOMPONENT_SPIF=1 -DCONFIG_GPIO_AS_PINRESET +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -34,10 +36,13 @@ -DFEATURE_BLE=1 -DFEATURE_CRYPTOCELL310=1 -DFEATURE_STORAGE=1 --DMBEDTLS_CONFIG_HW_SUPPORT --DMBED_BUILD_TIMESTAMP=1670864083.6341271 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447154.5646534 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_CONFIG_HW_SUPPORT -DNRF52840_XXAA -DNRF52_PAN_20 -DSWI_DISABLE0 @@ -63,11 +68,6 @@ -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -DWSF_MAX_HANDLERS=10 --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/EDGE_CONTROL/includes.txt b/variants/EDGE_CONTROL/includes.txt index 2c648b90e..238ddb925 100644 --- a/variants/EDGE_CONTROL/includes.txt +++ b/variants/EDGE_CONTROL/includes.txt @@ -128,23 +128,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/EDGE_CONTROL/libs/libmbed.a b/variants/EDGE_CONTROL/libs/libmbed.a index 0a63a3481..69085f107 100644 Binary files a/variants/EDGE_CONTROL/libs/libmbed.a and b/variants/EDGE_CONTROL/libs/libmbed.a differ diff --git a/variants/EDGE_CONTROL/mbed_config.h b/variants/EDGE_CONTROL/mbed_config.h index bbaf8eed7..83a45d8be 100644 --- a/variants/EDGE_CONTROL/mbed_config.h +++ b/variants/EDGE_CONTROL/mbed_config.h @@ -201,6 +201,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/GIGA/defines.txt b/variants/GIGA/defines.txt index dccae1a77..53a08c42f 100644 --- a/variants/GIGA/defines.txt +++ b/variants/GIGA/defines.txt @@ -44,7 +44,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1675161895.788852 +-DMBED_BUILD_TIMESTAMP=1690447383.8050008 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/GIGA/libs/libmbed.a b/variants/GIGA/libs/libmbed.a index 0aa148275..7b1e6bb8f 100644 Binary files a/variants/GIGA/libs/libmbed.a and b/variants/GIGA/libs/libmbed.a differ diff --git a/variants/GIGA/mbed_config.h b/variants/GIGA/mbed_config.h index 31bfc723c..460ac941c 100644 --- a/variants/GIGA/mbed_config.h +++ b/variants/GIGA/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/NANO_RP2040_CONNECT/defines.txt b/variants/NANO_RP2040_CONNECT/defines.txt index 369919919..85f8bdb41 100644 --- a/variants/NANO_RP2040_CONNECT/defines.txt +++ b/variants/NANO_RP2040_CONNECT/defines.txt @@ -1,6 +1,8 @@ -DARM_MATH_CM0PLUS +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 +-D__CORTEX_M0PLUS -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 @@ -17,9 +19,11 @@ -DDEVICE_USBDEVICE=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 --DMBEDTLS_ENTROPY_NV_SEED --DMBED_BUILD_TIMESTAMP=1670863511.0757143 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690446969.4415529 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM +-DMBEDTLS_ENTROPY_NV_SEED -DPICO_FLASH_SIZE_BYTES=16*1024*1024 -DPICO_NO_BINARY_INFO=1 -DPICO_ON_DEVICE=1 @@ -31,18 +35,14 @@ -DTARGET_LIKE_CORTEX_M0 -DTARGET_LIKE_MBED -DTARGET_M0P +-DTARGET_memmap_default -DTARGET_NAME=NANO_RP2040_CONNECT -DTARGET_NANO_RP2040_CONNECT -DTARGET_RASPBERRYPI -DTARGET_RELEASE -DTARGET_RP2040 --DTARGET_memmap_default -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M0PLUS --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/NANO_RP2040_CONNECT/includes.txt b/variants/NANO_RP2040_CONNECT/includes.txt index f42afe795..d84e91a12 100644 --- a/variants/NANO_RP2040_CONNECT/includes.txt +++ b/variants/NANO_RP2040_CONNECT/includes.txt @@ -65,23 +65,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NANO_RP2040_CONNECT/libs/libmbed.a b/variants/NANO_RP2040_CONNECT/libs/libmbed.a index 83d5e58de..276e5d120 100644 Binary files a/variants/NANO_RP2040_CONNECT/libs/libmbed.a and b/variants/NANO_RP2040_CONNECT/libs/libmbed.a differ diff --git a/variants/NANO_RP2040_CONNECT/mbed_config.h b/variants/NANO_RP2040_CONNECT/mbed_config.h index 08a14dc14..62a29941f 100644 --- a/variants/NANO_RP2040_CONNECT/mbed_config.h +++ b/variants/NANO_RP2040_CONNECT/mbed_config.h @@ -141,6 +141,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/NICLA/defines.txt b/variants/NICLA/defines.txt index a68b2f253..954f8bbbe 100644 --- a/variants/NICLA/defines.txt +++ b/variants/NICLA/defines.txt @@ -1,16 +1,18 @@ -DARM_MATH_CM4 -DBOARD_PCA10040 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 -DCOMPONENT_SPIF=1 -DCONFIG_NFCT_PINS_AS_GPIOS +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_ITM=1 -DDEVICE_LPTICKER=1 @@ -29,7 +31,10 @@ -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 -DFEATURE_BLE=1 --DMBED_BUILD_TIMESTAMP=1670864134.7724268 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447190.2057042 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS -DNRF52 @@ -69,11 +74,6 @@ -DTARGET_SOFTDEVICE_NONE -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/NICLA/includes.txt b/variants/NICLA/includes.txt index 4cc4b394b..e05af8b4e 100644 --- a/variants/NICLA/includes.txt +++ b/variants/NICLA/includes.txt @@ -123,23 +123,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NICLA/libs/libmbed.a b/variants/NICLA/libs/libmbed.a index e6c56cfe7..3033bd740 100644 Binary files a/variants/NICLA/libs/libmbed.a and b/variants/NICLA/libs/libmbed.a differ diff --git a/variants/NICLA/mbed_config.h b/variants/NICLA/mbed_config.h index 0f7a8772d..02cc24c06 100644 --- a/variants/NICLA/mbed_config.h +++ b/variants/NICLA/mbed_config.h @@ -31,7 +31,7 @@ #define BLE_FEATURE_PHY_MANAGEMENT 1 // set by library:ble #define BLE_FEATURE_PRIVACY 0 // set by application[*] #define BLE_FEATURE_SECURE_CONNECTIONS 0 // set by application[*] -#define BLE_FEATURE_SECURITY 0 // set by application[*] +#define BLE_FEATURE_SECURITY 1 // set by application[*] #define BLE_FEATURE_SIGNING 0 // set by application[*] #define BLE_FEATURE_WHITELIST 0 // set by application[*] #define BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION 0 // set by application[*] @@ -199,6 +199,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora @@ -305,7 +306,7 @@ #define MBED_CONF_RTOS_PRESENT 1 // set by library:rtos #define MBED_CONF_RTOS_SEMAPHORE_NUM 0 // set by library:rtos #define MBED_CONF_RTOS_THREAD_NUM 0 // set by library:rtos -#define MBED_CONF_RTOS_THREAD_STACK_SIZE 1024 // set by application[*] +#define MBED_CONF_RTOS_THREAD_STACK_SIZE 768 // set by application[*] #define MBED_CONF_RTOS_THREAD_USER_STACK_SIZE 0 // set by library:rtos #define MBED_CONF_RTOS_TIMER_NUM 0 // set by library:rtos #define MBED_CONF_RTOS_TIMER_THREAD_STACK_SIZE 768 // set by library:rtos @@ -385,9 +386,7 @@ #define LHCI_ENABLE_VS 0 // defined by library:cordio-nordic-ll #define LL_MAX_PER_SCAN 3 // defined by library:cordio-nordic-ll #define MBEDTLS_CIPHER_MODE_CTR // defined by library:SecureStore -#define MBED_HEAP_STATS_ENABLED 1 // defined by application #define MBED_MEM_TRACING_ENABLED 1 // defined by application -#define MBED_STACK_STATS_ENABLED 1 // defined by application #define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 8 // defined by application #define NRFX_WDT_ENABLED 1 // defined by application #define NSAPI_PPP_AVAILABLE (MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED) // defined by library:ppp diff --git a/variants/NICLA_VISION/cflags.txt b/variants/NICLA_VISION/cflags.txt index ac9f710b6..8c5eb01b0 100644 --- a/variants/NICLA_VISION/cflags.txt +++ b/variants/NICLA_VISION/cflags.txt @@ -19,7 +19,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/NICLA_VISION/cxxflags.txt b/variants/NICLA_VISION/cxxflags.txt index 2dec88933..24d860cfa 100644 --- a/variants/NICLA_VISION/cxxflags.txt +++ b/variants/NICLA_VISION/cxxflags.txt @@ -21,7 +21,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/NICLA_VISION/defines.txt b/variants/NICLA_VISION/defines.txt index 6fa69c4e3..8e73def76 100644 --- a/variants/NICLA_VISION/defines.txt +++ b/variants/NICLA_VISION/defines.txt @@ -45,7 +45,7 @@ -DFLOW_SILENT -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1673362829.88069 +-DMBED_BUILD_TIMESTAMP=1690447224.0712476 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/NICLA_VISION/includes.txt b/variants/NICLA_VISION/includes.txt index b44ead3f0..4bef4f58c 100644 --- a/variants/NICLA_VISION/includes.txt +++ b/variants/NICLA_VISION/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NICLA_VISION/libs/libmbed.a b/variants/NICLA_VISION/libs/libmbed.a index e4888bdaf..66947671c 100644 Binary files a/variants/NICLA_VISION/libs/libmbed.a and b/variants/NICLA_VISION/libs/libmbed.a differ diff --git a/variants/NICLA_VISION/linker_script.ld b/variants/NICLA_VISION/linker_script.ld index f634db472..0b00d41d9 100644 --- a/variants/NICLA_VISION/linker_script.ld +++ b/variants/NICLA_VISION/linker_script.ld @@ -1,12 +1,14 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 0x1c0000 + FLASH (rx) : ORIGIN = 0x8040000, LENGTH = CM4_BINARY_START - 0x8040000 DTCMRAM (rwx) : ORIGIN = 0x20000000 + (((166 * 4) + 7) & 0xFFFFFFF8), LENGTH = 128K - (((166 * 4) + 7) & 0xFFFFFFF8) RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 0x80000 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +__OPENAMP_region_start__ = 0x38000400; +__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K; ENTRY(Reset_Handler) SECTIONS { @@ -92,6 +94,15 @@ SECTIONS __bss_end__ = .; _ebss = .; } > RAM + .openamp_section (NOLOAD) : { + . = ABSOLUTE(0x38000000); + *(.resource_table) + } >RAM_D3 AT > FLASH + .pdm_section (NOLOAD) : { + . = ABSOLUTE(0x3800FC00); + *(.pdm_buffer) + } > RAM_D3 + .heap (COPY): { __end__ = .; diff --git a/variants/NICLA_VISION/mbed_config.h b/variants/NICLA_VISION/mbed_config.h index 3cb8deaa9..ed8376f00 100644 --- a/variants/NICLA_VISION/mbed_config.h +++ b/variants/NICLA_VISION/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/OPTA/cflags.txt b/variants/OPTA/cflags.txt index ac9f710b6..8c5eb01b0 100644 --- a/variants/OPTA/cflags.txt +++ b/variants/OPTA/cflags.txt @@ -19,7 +19,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/OPTA/cxxflags.txt b/variants/OPTA/cxxflags.txt index 2dec88933..24d860cfa 100644 --- a/variants/OPTA/cxxflags.txt +++ b/variants/OPTA/cxxflags.txt @@ -21,7 +21,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/OPTA/defines.txt b/variants/OPTA/defines.txt index 9232d9eb8..970b3bc5d 100644 --- a/variants/OPTA/defines.txt +++ b/variants/OPTA/defines.txt @@ -44,7 +44,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1673362585.5704832 +-DMBED_BUILD_TIMESTAMP=1690447327.7181125 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/OPTA/includes.txt b/variants/OPTA/includes.txt index 83aacc793..413e84b71 100644 --- a/variants/OPTA/includes.txt +++ b/variants/OPTA/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/OPTA/libs/libmbed.a b/variants/OPTA/libs/libmbed.a index ddd7de3fc..aec91ccba 100644 Binary files a/variants/OPTA/libs/libmbed.a and b/variants/OPTA/libs/libmbed.a differ diff --git a/variants/OPTA/linker_script.ld b/variants/OPTA/linker_script.ld index f634db472..8941b72a6 100644 --- a/variants/OPTA/linker_script.ld +++ b/variants/OPTA/linker_script.ld @@ -1,12 +1,14 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 0x1c0000 + FLASH (rx) : ORIGIN = 0x8040000, LENGTH = CM4_BINARY_START - 0x8040000 DTCMRAM (rwx) : ORIGIN = 0x20000000 + (((166 * 4) + 7) & 0xFFFFFFF8), LENGTH = 128K - (((166 * 4) + 7) & 0xFFFFFFF8) RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 0x80000 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +__OPENAMP_region_start__ = 0x38000400; +__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K; ENTRY(Reset_Handler) SECTIONS { @@ -92,6 +94,20 @@ SECTIONS __bss_end__ = .; _ebss = .; } > RAM + .openamp_section (NOLOAD) : { + . = ABSOLUTE(0x38000000); + *(.resource_table) + } >RAM_D3 AT > FLASH + .pdm_section (NOLOAD) : { + . = ABSOLUTE(0x3800FC00); + *(.pdm_buffer) + } > RAM_D3 + _dtcm_lma = __etext + SIZEOF(.data); + .dtcm : AT(_dtcm_lma) { + _sdtcm = .; + *(.dtcm*) + _edtcm = .; + } > DTCMRAM .heap (COPY): { __end__ = .; diff --git a/variants/OPTA/mbed_config.h b/variants/OPTA/mbed_config.h index cade4b32b..c0485cbf8 100644 --- a/variants/OPTA/mbed_config.h +++ b/variants/OPTA/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/OPTA/pins_arduino.h b/variants/OPTA/pins_arduino.h index 62bbc478f..25d6e8c06 100644 --- a/variants/OPTA/pins_arduino.h +++ b/variants/OPTA/pins_arduino.h @@ -130,13 +130,18 @@ static const uint8_t SCK = PIN_SPI_SCK; #define PIN_WIRE_SDA (11u) #define PIN_WIRE_SCL (12u) -#define SERIAL_HOWMANY 2 +#define SERIAL_HOWMANY 3 #define SERIAL1_TX (digitalPinToPinName(PIN_SERIAL_TX)) #define SERIAL1_RX (digitalPinToPinName(PIN_SERIAL_RX)) #define SERIAL2_TX PB_10 #define SERIAL2_RX PB_11 +#define SERIAL3_TX PB_9 +#define SERIAL3_RX PH_14 +#define SERIAL3_RTS PA_15 +#define SERIAL3_CTS PB_15 + #define SERIAL_CDC 1 #define HAS_UNIQUE_ISERIAL_DESCRIPTOR @@ -184,11 +189,6 @@ void _ontouch1200bps_(); #define RS485_DEFAULT_DE_PIN PB_14 #define RS485_DEFAULT_RE_PIN PB_13 -#define SerialLoRa Serial3 -#define LORA_BOOT0 (PG_7) -#define LORA_RESET (PC_7) -#define LORA_IRQ_DUMB (PJ_11) - #define CRYPTO_WIRE Wire1 #define USB_MAX_POWER (500) diff --git a/variants/PORTENTA_H7_M4/defines.txt b/variants/PORTENTA_H7_M4/defines.txt index abd13279b..90277e8fe 100644 --- a/variants/PORTENTA_H7_M4/defines.txt +++ b/variants/PORTENTA_H7_M4/defines.txt @@ -42,7 +42,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1674127650.1797109 +-DMBED_BUILD_TIMESTAMP=1690447099.1347957 -D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS diff --git a/variants/PORTENTA_H7_M4/libs/libmbed.a b/variants/PORTENTA_H7_M4/libs/libmbed.a index a1c9c8e12..297d3dfdd 100644 Binary files a/variants/PORTENTA_H7_M4/libs/libmbed.a and b/variants/PORTENTA_H7_M4/libs/libmbed.a differ diff --git a/variants/PORTENTA_H7_M4/mbed_config.h b/variants/PORTENTA_H7_M4/mbed_config.h index 936622de4..20f47ae62 100644 --- a/variants/PORTENTA_H7_M4/mbed_config.h +++ b/variants/PORTENTA_H7_M4/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/PORTENTA_H7_M7/defines.txt b/variants/PORTENTA_H7_M7/defines.txt index 5162a4fad..d4eec2164 100644 --- a/variants/PORTENTA_H7_M7/defines.txt +++ b/variants/PORTENTA_H7_M7/defines.txt @@ -2,12 +2,14 @@ -DARM_MATH_CM7 -DBT_UART_NO_3M_SUPPORT -DCM4_BOOT_BY_APPLICATION +-D__CMSIS_RTOS -DCOMPONENT_4343W_FS=1 -DCOMPONENT_CYW43XXX=1 -DCOMPONENT_FLASHIAP=1 -DCOMPONENT_QSPIF=1 -DCOMPONENT_WHD=1 -DCORE_CM7 +-D__CORTEX_M7 -DCYW43XXX_UNBUFFERED_UART -DDEVICE_ANALOGIN=1 -DDEVICE_ANALOGOUT=1 @@ -16,8 +18,8 @@ -DDEVICE_EMAC=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_MPU=1 @@ -32,8 +34,8 @@ -DDEVICE_SERIAL_FC=1 -DDEVICE_SLEEP=1 -DDEVICE_SPI=1 --DDEVICE_SPISLAVE=1 -DDEVICE_SPI_ASYNCH=1 +-DDEVICE_SPISLAVE=1 -DDEVICE_STDIO_MESSAGES=1 -DDEVICE_TRNG=1 -DDEVICE_USBDEVICE=1 @@ -41,11 +43,14 @@ -DDEVICE_WATCHDOG=1 -DEXTRA_IDLE_STACK_REQUIRED -DFEATURE_BLE=1 +-D__FPU_PRESENT=1 -DLSE_STARTUP_TIMEOUT=200 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447044.864524 +-D__MBED_CMSIS_RTOS_CM +-DMBED_TICKLESS -DMBEDTLS_FS_IO -DMBEDTLS_SHA1_C --DMBED_BUILD_TIMESTAMP=1670863887.7329667 --DMBED_TICKLESS -DMETAL_INTERNAL -DMETAL_MAX_DEVICE_REGIONS=2 -DNO_ATOMIC_64_SUPPORT @@ -77,11 +82,6 @@ -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -DVIRTIO_MASTER_ONLY --D__CMSIS_RTOS --D__CORTEX_M7 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/PORTENTA_H7_M7/includes.txt b/variants/PORTENTA_H7_M7/includes.txt index 1aef9dc4e..abddc6f96 100644 --- a/variants/PORTENTA_H7_M7/includes.txt +++ b/variants/PORTENTA_H7_M7/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/PORTENTA_H7_M7/libs/libmbed.a b/variants/PORTENTA_H7_M7/libs/libmbed.a index e2fec309b..d262766d7 100644 Binary files a/variants/PORTENTA_H7_M7/libs/libmbed.a and b/variants/PORTENTA_H7_M7/libs/libmbed.a differ diff --git a/variants/PORTENTA_H7_M7/linker_script.ld b/variants/PORTENTA_H7_M7/linker_script.ld index 17d5ac032..8941b72a6 100644 --- a/variants/PORTENTA_H7_M7/linker_script.ld +++ b/variants/PORTENTA_H7_M7/linker_script.ld @@ -30,6 +30,12 @@ SECTIONS *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) + *ltrans0*.o(.rodata*) + *ltrans1*.o(.rodata*) + *ltrans2*.o(.rodata*) + *ltrans3*.o(.rodata*) + *ltrans4*.o(.rodata*) + *lib*.o(.rodata*) } > FLASH .ARM.extab : { diff --git a/variants/PORTENTA_H7_M7/mbed_config.h b/variants/PORTENTA_H7_M7/mbed_config.h index 5eb2392ed..a6f5ffd53 100644 --- a/variants/PORTENTA_H7_M7/mbed_config.h +++ b/variants/PORTENTA_H7_M7/mbed_config.h @@ -196,6 +196,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/PORTENTA_X8/defines.txt b/variants/PORTENTA_X8/defines.txt index 6b5ab9bb7..7541674f7 100644 --- a/variants/PORTENTA_X8/defines.txt +++ b/variants/PORTENTA_X8/defines.txt @@ -1,16 +1,18 @@ -DARM_MATH_CM4 -DCM4_BOOT_BY_APPLICATION +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 -DCORE_CM4 +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_ANALOGOUT=1 -DDEVICE_CAN=1 -DDEVICE_CRC=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -23,18 +25,21 @@ -DDEVICE_SERIAL_FC=1 -DDEVICE_SLEEP=1 -DDEVICE_SPI=1 --DDEVICE_SPISLAVE=1 -DDEVICE_SPI_ASYNCH=1 +-DDEVICE_SPISLAVE=1 -DDEVICE_STDIO_MESSAGES=1 -DDEVICE_TRNG=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 -DEXTRA_IDLE_STACK_REQUIRED --DMBEDTLS_FS_IO --DMBEDTLS_SHA1_C --DMBED_BUILD_TIMESTAMP=1670864288.6141653 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447283.7087135 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_FS_IO +-DMBEDTLS_SHA1_C -DMETAL_INTERNAL -DMETAL_MAX_DEVICE_REGIONS=2 -DNO_ATOMIC_64_SUPPORT @@ -64,11 +69,6 @@ -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -DVIRTIO_SLAVE_ONLY --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/PORTENTA_X8/includes.txt b/variants/PORTENTA_X8/includes.txt index 2d996d085..e071ee154 100644 --- a/variants/PORTENTA_X8/includes.txt +++ b/variants/PORTENTA_X8/includes.txt @@ -96,23 +96,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/PORTENTA_X8/libs/libmbed.a b/variants/PORTENTA_X8/libs/libmbed.a index 20a65cddb..7d9dd3a47 100644 Binary files a/variants/PORTENTA_X8/libs/libmbed.a and b/variants/PORTENTA_X8/libs/libmbed.a differ diff --git a/variants/PORTENTA_X8/mbed_config.h b/variants/PORTENTA_X8/mbed_config.h index 07c548a8b..3a0e9f454 100644 --- a/variants/PORTENTA_X8/mbed_config.h +++ b/variants/PORTENTA_X8/mbed_config.h @@ -150,6 +150,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/RASPBERRY_PI_PICO/defines.txt b/variants/RASPBERRY_PI_PICO/defines.txt index 64f7cd8fa..15fb053eb 100644 --- a/variants/RASPBERRY_PI_PICO/defines.txt +++ b/variants/RASPBERRY_PI_PICO/defines.txt @@ -1,6 +1,8 @@ -DARM_MATH_CM0PLUS +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 +-D__CORTEX_M0PLUS -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 @@ -17,9 +19,11 @@ -DDEVICE_USBDEVICE=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 --DMBEDTLS_ENTROPY_NV_SEED --DMBED_BUILD_TIMESTAMP=1670863580.9430058 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447021.82633 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM +-DMBEDTLS_ENTROPY_NV_SEED -DPICO_NO_BINARY_INFO=1 -DPICO_ON_DEVICE=1 -DPICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 @@ -30,18 +34,14 @@ -DTARGET_LIKE_CORTEX_M0 -DTARGET_LIKE_MBED -DTARGET_M0P +-DTARGET_memmap_default -DTARGET_NAME=RASPBERRY_PI_PICO -DTARGET_RASPBERRYPI -DTARGET_RASPBERRY_PI_PICO -DTARGET_RELEASE -DTARGET_RP2040 --DTARGET_memmap_default -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M0PLUS --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/RASPBERRY_PI_PICO/includes.txt b/variants/RASPBERRY_PI_PICO/includes.txt index d538e6c6d..ec0bfda37 100644 --- a/variants/RASPBERRY_PI_PICO/includes.txt +++ b/variants/RASPBERRY_PI_PICO/includes.txt @@ -65,23 +65,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/RASPBERRY_PI_PICO/libs/libmbed.a b/variants/RASPBERRY_PI_PICO/libs/libmbed.a index d7e1de69c..78edaa82d 100644 Binary files a/variants/RASPBERRY_PI_PICO/libs/libmbed.a and b/variants/RASPBERRY_PI_PICO/libs/libmbed.a differ diff --git a/variants/RASPBERRY_PI_PICO/mbed_config.h b/variants/RASPBERRY_PI_PICO/mbed_config.h index 08a14dc14..62a29941f 100644 --- a/variants/RASPBERRY_PI_PICO/mbed_config.h +++ b/variants/RASPBERRY_PI_PICO/mbed_config.h @@ -141,6 +141,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy